ECMAScript-6学习笔记(三):箭头函数的this

this真是个谜。箭头函数加上this更是迷雾重重。

网上部分资料对于this在箭头函数中解释是:箭头函数的this是由它定义时所在对象决定的。对于这个解释,可能是表述关系 ,我也不能说它错,对此也不多解读,不过我认为这个解释不能让我们真正理解箭头函数this。

箭头函数中是没有不会创造独立的上下文的,它的上下文来自enclosing context,即来自其所在上下文的this作为自己的this。

下面通过例子来解读下这个定义:

1
2
3
4
5
var person = {
name: "test",
shout: () => console.log(this.name)
}
person.shout();

如果按照this是由定义时所在对象决定的解释,那么上述代码应该输出为test,然而事实上我们测试得到没有输出。

事实上,箭头函数的this是其所在上下文的this决定的。我们结合上一个例子来解析一下,这里的箭头函数() => console.log(this.name)的上下文是全局上下文也就是window,而这里的name: "test"实际上是person.name,因此person.shout()调用shout函数时,this指向全局上下文,而此时全局上下文中没有定义name,因此不会有任何输出。

当我们将代码作如下修改:

1
2
3
4
5
6
7
8
var person = {
name: "test",
shout(){
const shout = () => console.log(this.name);
return shout;
}
}
person.shout()();

此时,() => console.log(this.name)中的this是由shout()的上下文的this决定的,当我们调用person.shout()时,shout()的上下文是person对象,因此箭头函数() => console.log(this.name)中的上下文将在person.shout()执行时就确定为person对象。因此,person.shout()()虽然执行时的上下文是window,但是箭头函数的this却是指向person对象。

为了加深理解,我们再来看另外一个典型的例子:

1
2
3
4
5
6
7
function Person(){
this.age = 0;
setInterval(() => {
this.age++;
}, 1000);
}
var p = new Person();

如果定时器内部的函数是普通函数,那么函数的上下文是全局window,但是改成箭头函数之后,我们根据前面的定义,() => { this.age++; }是this是由所在的上下文决定的,因此当我们执行var p = new Person()时,Person函数内部的上下文的this便指向p,因此箭头函数内部的上下文也必定是p,因此this.age++可以正常执行。

总而言之,箭头函数的this是由箭头函数定义时候所处的上下文决定的。

欢迎指正交流。未经允许,请勿转载。