Js基础复习篇一

60次阅读

共计 1608 个字符,预计需要花费 5 分钟才能阅读完成。

根据大佬的 github 的讲解,来巩固 js。感谢大佬的分享与讲解
1、var、let、const

for (var i = 0; i < 3; i++) {setTimeout(() => console.log(i), 1)
}//3,3,3
for (let i = 0; i < 3; i++) {setTimeout(() => console.log(i), 1)
}//0,1,2
由于 JavaScript 的事件循环,setTimeout 回调会在遍历结束后才执行。因为在第一个遍历中遍历 i 是通过 var 关键字声明的,所以这个值是全局作用域下的。在遍历过程中,我们通过一元操作符 ++ 来每次递增 i 的值。当 setTimeout 回调执行的时候,i 的值等于 3。在第二个遍历中,遍历 i 是通过 let 关键字声明的:通过 let 和 const 关键字声明的变量是拥有块级作用域(指的是任何在 {} 中的内容)。在每次的遍历过程中,i 都有一个新值,并且每个值都在循环内的作用域中。

事件队列(Task Queue)

js 引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。当一个异步事件返回结果后,js 会将这个事件加入与当前执行栈不同的另一个队列,我们称之为事件队列。被放入事件队列不会立刻执行其回调,而是等待当前执行栈中的所有任务都执行完毕,主线程处于闲置状态时,** 主线程 ** 会去查找事件队列是否有任务。如果有,那么主线程会从中取出排在第一位的事件,并把这个事件对应的回调放入执行栈中,然后执行其中的同步代码...,如此反复,这样就形成了一个无限的循环。这就是这个过程被称为“** 事件循环(Event Loop**)”的原因。

当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行
2、this 指向问题。
this 永远指向最后调用它的那个对象

const shape = {
  radius: 10,
  diameter() {return this.radius * 2},
  perimeter: () => 2 * Math.PI * this.radius}
shape.diameter()//20
shape.perimeter()//NAN
例 2.
var name = "windows";
var a = {
    name : "in",
    func1: function () {console.log(this.name)     
    },
    func2: function () {
        var _this = this;
        setTimeout(function() {_this.func1()
        },100);
       // setTimeout(()=> {//   _this.func1()
       // },100);
    }
};
a.func2()       // in  _this=this
a.func2()       // in  箭头函数  

a: 箭头函数
箭头函数的 this 始终指向函数定义时的 this,而非执行时。箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined。
b: 通过给_this =this 将 this 绑定到固定值
c:apply,call,bind

var name = "windows";
var a = {
    name : "in",
    func1: function () {console.log(this.name)     
    },
    func2: function () {
        var _this = this;
        setTimeout(function() {_this.func1()
        }.apply(a),100);
       // setTimeout(()=> {//   this.func1()
       // }.call(a),100);
       // setTimeout(()=> {//   this.func1()
       // }.bind(a)(),100);
    }
};

bind 是创建一个新的函数,必须要手动去调用:

正文完
 0