1
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,而没有变化,

jcbound 14
2019-05-15 提问

查看全部 4 个回答

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。

推广链接