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一次都没更新。
这是阮一峰es6中说的,我也理解s2的this指向window对象,但是不理解为什么值是0,而没有变化,
箭头函数,this的作用域跟父函数一致,所以
setInterval(() => this.s1++, 1000);
的this指向和this.s1 = 0;
一致。非箭头函数的
setInterval(function () {this.s2++;}, 1000);
的this指向是window,为什么是window?因为这里是一个匿名函数。为什么匿名函数就指向window呢?这就牵涉到this的作用域问题。
在js中,this这个指向并不是在函数声明的时候确定的,而是函数执行的时候才确定的,谁调用了这个方法,这个方法的this就指向谁。
根据
var timer = new Timer();
和timer.s1
,我们知道,实例化Timer的是timer,通过timer调用s1,所以this指向timer,这个是没问题的。但是匿名函数没人调他,根据设定,没人调那就找不到负责人,私生子?只能委托给window,所以匿名函数的this都指向window。
所以
setInterval(function () {this.s2++;}, 1000);
就相当于setInterval(function () {window.s2++;}, 1000);
很显然,timer.s2根本就没动,自然就是0.这个时候如果你打印window.s2,结果就是NaN,为什么?
window.s2 这个变量并没有声明,那就是undefined,一个undefined的变量自增,就是NaN。