ES6之箭头函数中的this
本文主要介绍箭头函数中的this
和普通函数的区别。
在讲箭头函数中的this之前我们先介绍一下普通函数中的this。
# 普通函数中的this
this指向它的直接调用者
默认的,非严格模式下,没找到直接调用者则指向window
严格模式下,没直接调用者的this是undefined
使用call,apply,bind绑定对象,则this指向被绑定的对象。
// ES5中
window.val = 1;
var obj = {
val: 2,
dbl: function () {
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
}
};
obj.dbl();
var func = obj.dbl;
func();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
输出:
// 输出结果
2 4 8 8
# 分析
val变量在没有指定对象前缀,默认从函数中找,找不到则从
window
中找全局变量, 即val *=2
就是window.val *= 2
,this.val
默认指的是obj.val
; 因为dbl()
第一次被obj
直接调用func()
没有任何前缀,类似于全局函数,即window.func
调用, 所以第二次调用的时候,this
指的是window
,val
指的是window.val
。第二次的结果受第一次的影响。
作用域链: 当在函数中使用一个变量的时候,首先在本函数内部查找该变量,如果找不到则找其父级函数,最后直到window,全局变量默认挂载在window对象下。
# 箭头函数中的this
箭头函数中的
this
对象就是定义时所在的对象,而不是使用时所在的对象不可以使用
new
命令创建实例不可以使用
argument
对象,该对象在函数体内不存在。如果要用,可以用rest
参数代替不可以使用
yield
命令,因此箭头函数不能用作Generator
函数。由于箭头函数没有自己的
this
,所以当然也就不能用call()
、apply()
、bind()
这些方法去改变this
的指向。
示例:
var obj = {
say: function () {
setTimeout(() => {
console.log(this);
});
}
}
obj.say();
2
3
4
5
6
7
8
输出:
obj
此时的 this指的是定义它的对象:obj, 而不是 window。
# 多层嵌套的箭头函数
var obj = {
say: function () {
var f1 = () => {
console.log(this); // obj
setTimeout(() => {
console.log(this); // obj
})
}
f1();
}
}
obj.say()
2
3
4
5
6
7
8
9
10
11
12
由于fa定义时所处的函数中的this是指向obj的,所以无论嵌套多少层都指向obj。
# 普通函数和箭头函数混杂嵌套
var obj = {
say: function () {
var f1 = function () {
console.log(this); // window, f1调用时,没有宿主对象,默认是window
setTimeout(() => {
console.log(this); // window
})
};
f1();
}
}
obj.say()
2
3
4
5
6
7
8
9
10
11
12
因为箭头函数所在的函数位置为f1,f1中的this是指向window,所以箭头函数的this与指向window。
# 箭头函数中使用call()、apply()、bind()
(function() {
return [
(() => this.x).bind({ x: 'inner' })()
];
}).call({ x: 'outer' });
2
3
4
5
输出:
["outer"]
由于箭头函数没有自己的this,所以使用bind()方法无法改变this的指向。
# 总结
箭头函数中的this
指向是固定的,并不是因为箭头函数内部有绑定this
的机制,实际原因是箭头函数内部没有this
,导致内部的this
就是外层代码块的this
。正因为它没有this
,所以也就不能用作构造函数。