ES6箭头函数作用域问题

在看阮一峰老师的ES6入门,在箭头函数那里有点不明白的

箭头函数this绑定定义时的作用域,这个好理解。

后者的this指向运行时所在的作用域(即全局对象)这是为什么?运行时不也在Timer()函数内部?为什么作用域变成全局的了?

function Timer() {

this.s1 = 0;

this.s2 = 0;

// 箭头函数

setInterval(() => this.s1++, 1000);

// 普通函数

setInterval(function () {

this.s2++;

}, 1000);

}

var timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100);

setTimeout(() => console.log('s2: ', timer.s2), 3100);

// s1: 3

// s2: 0

上面代码中,Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数。前者的this绑定定义时所在的作用域(即Timer函数),后者的this指向运行时所在的作用域(即全局对象)。所以,3100 毫秒之后,timer.s1被更新了 3 次,而timer.s2一次都没更新。

回答

function () {

this.s2++;

}

执行的时候作用域已经是全局作用域啦。

要想s2也改变,可以这样

function Timer() {

this.s1 = 0;

this.s2 = 0;

// 箭头函数

setInterval(() => this.s1++, 1000);

// 普通函数

setInterval((function () {

this.s2++;

}).bind(this), 1000);

}

var timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100);

setTimeout(() => console.log('s2: ', timer.s2), 3100);

// s1 3

// s2 3

箭头函数没有自己的作用域,其作用域来自其父作用域。如果其父级还是个箭头函数,就继续往上找,直到根作用域为止。

就记住上面加粗的这句话就行了。这是 ES6 的规定,至于为什么这么规定,ECMA 组织没说。

正因如此,箭头函数内部访问 thissuperargumentsnew.target 这几个特殊对象,都会去其父作用域里找。


可以看我以前的一个回答,更具体一些:https://segmentfault.com/q/10...

image.png

还是要好好理解 运行时作用域 这个概念。

箭头函数理解了,这里跳过不说。

单说这个普通函数。

因为 setInterval 会将回到函数放入 宏任务 中。简单的理解就是它是异步执行的,所以当它执行时, 它的执行环境其实是在 window 上的。

所以回调中的 this.s2 其实就是调用 window.s2

timer.s2 声明之后并没有被调用,当然是一次都没更新了。

以上是 ES6箭头函数作用域问题 的全部内容, 来源链接: utcz.com/a/25115.html

回到顶部