首先我们需要明白两点:
- 箭头函数是没有自己的this的;
- 箭头函数不是单纯的一个语法糖,不要将其完全等同于以前声明函数的那种写法;
现在我们来解释第一点:
箭头函数是没有自己的this的
引用自MDN关于箭头函数的描述:
箭头功能不会创建自己的this;它使用封闭执行上下文的this值
这句话具体什么意思呢?我们来看下代码:(又从MDN般代码了,但是确实是我看过最容易理解的例子了)
var adder = {
base : 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base : 2
};
return f.call(b, a);
}
};
console.log(adder.add(1)); // 输出 2
console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3 ——译者注)
首先adder.add(1)执行会对adder.base的值进行 +1 输出2,这个没有什么问题;
然后adder.addThruCall(1),此时,如果箭头函数不是使用的封闭执行上下文的this的话,如果有自己的this,通过f.call(b, a) 这个代码,里面的this.base的this应该指向的是b这个对象,然后拿到b.base为2的值,最后 +1 的结果应该是3,但是显然结果并不是3,还是2,说明拿到的仍然是adder.base,this 依然指向的是外部作用域的this(封闭执行上下文感觉并不少非常好理解)。
既然箭头函数没有自己的this,那么通过call,apply这些对它的this值进行操作自然也是没有意义的。
所以回到第一点:箭头函数没有自己的this。如果你在箭头函数内部使用了this,那么这个this 实际指向的是最近一层作用域的this。不但没有自己的this,
再来讲一下第二点:
箭头函数不是单纯的一个语法糖,不要将其完全等同于以前声明函数的那种写法
当箭头函数内部没有用到this的时候
var foo = () => {console.log('arrow function')}
//上面写法是等于下面的
var foo = function(){
console.log('arrow function');
}
如果箭头函数内部使用了this
var foo = () => {console.log(this.age)}
// 并不是这样,虽然结果可能和这种操作得到的结果一样,但是背后的原理完全不同。
var foo = function(){
console.log(this.age);
}.bind(this);
箭头函数在词法作用域上已经绑定了this。通过apply,call只是相当于传了个参数而已,并不会对this产生影响。箭头函数也不会绑定arguments,super,new Target()。
var arguments = 12;
//undefined
var arr = () => arguments;
//undefined
arr();
//12
var arr2 = function(){return arguments;}
//undefined
arr2()
//[callee: ƒ, Symbol(Symbol.iterator): ƒ]
从这个可以看出来,通过箭头函数访问arguments对象时,并不是访问自身的arguments对象,而是访问的外部作用域的aruments对象,这时候它的外部作用域是window对象,所以返回12(window.arguments == 12);
但是下面那种写法实际访问的就是自身的arguments对象了。
网友评论