关于ES6 箭头函数中 this 指向的问题,以及 call

在看阮一峰老师的 ES6 教程的时候,在箭头函数这一章的,关于 this 指向的这一小节中,有这样一个例子

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

然后关于这个例子的解释是:

上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向 函数定义生效时 所在的对象(本例是{id: 42}),所以输出的是42。

但是这个例子中调用 foo 函数的方式时使用了 call 方法,导致我对这里的理解产生了混乱。
于是我试着不使用 call 方法调用这个函数

function foo() {
    setTimeout( () => {
        console.log('this.id:',this.id);
    },100);
}

var id = 21;

foo({ id: 42});             // 21
foo.call({ id: 42});        // 42

这个时候输出的 id 为21,是指向 window的

所以有点儿搞不懂这个例子,应该是用来说明,这里的this指向是被 箭头函数所改变的,但就我自己的理解感觉像是被 call函数改变的。

因为对于this指向我一直都不是特别清楚,我觉得自己应该是哪里的理解出现了误解,已经试着查了相关的知识点,但自己始终无法想通,希望有人可以解释下这个例子0.0

阅读 2.8k
1 个回答

首先,先不管箭头函数,假设setTimeout里面是一个普通函数,而foo函数如下所示:

function foo() {
    console.log('this.id:',this.id); // this.id: 42
    setTimeout( function () {
        console.log('this.id:',this.id); // this.id: 21
    },100);
}

执行 foo.call({id: 42}) 后,第一行输出了42,而setTimeout里面输出了21。
第一行输出42,是因为call函数改变了foo的指针执行,指向为{id: 42}

而第二行为什么输出21,是因为setTimeout是挂载在window下面的。setTimeout实际上又改变了this的指针指向,将this又指向了window。因此输出21。


而 改成箭头函数之后,foo函数如下

function foo() {
    console.log('this.id:',this.id); // this.id: 42
    setTimeout( () => {
        console.log('this.id:',this.id); // this.id: 42
    },100);
}

执行foo.call({id: 42})后,为什么setTimeout 里面还是输出了42呢,因为箭头函数导致this总是指向 函数定义生效时 所在的对象(本例是{id: 42}),因此才会输出42。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题