普通函数中this
的绑定是很复杂多变的,ES6箭头函数=>
以特定的方式改变this
的行为特性,解决this
相关编码的
一个特殊又常见的痛点。
箭头函数也不总是比普通函数好,当这个函数越长,=>
带来的好处越小,这个函数越短,=>
带来的好处越大。所以
只在确实需要简短的在线函数表达式的时候才用=>
,而对于那些一般长度的函数则无需改变。
var controller = {
makeRequest: function(){
var self = this;
btn.addEventListener( "click", function(){
// ..
self.makeRequest();
}, false );
}
};
在这个例子中,我们使用var self = this
这一Hack,然后使用self.makeRequest
,因为我们传入addEVentListener
的回调函数内部,this
绑定和makeRequest()
本身的this
绑定不一样。普通函数中的this绑定是动态的,我们需要通过self
变量依赖词法作用域的可预测性。
箭头函数中的this
绑定不是动态的,而是词法的。
var controller = {
makeRequest: function(){
btn.addEventListener( "click", () => {
// ..
this.makeRequest();
}, false );
}
};
我们使用=>
箭头函数替代普通函数,箭头函数回调中的词法this
和makeRequest()
中是一样的。=>
就是var self = this
的词法替代形式。
我们使用Babel
转换一下:
发现,在使用=>
之前,也就是箭头函数的外层,先使用var self = this
保存了this
再看一个例子:
var controller = {
makeRequest: () => {
// ..
this.helper();
},
helper: () => {
// ..
}
};
controller.makeRequest();
尽管我们以 controller.makeRequest(..) 的形式调用,this.helper 引用还是会失败,因为
这里的 this 并不像平常一样指向 controller。那么它指向哪里呢?它是从包围的作用域中
词法继承而来的 this。在前面的代码中也就是全局作用域,其中 this 指向那个全局对象。
- 箭头函数没有自己的
this
,只有词法this
,继承自父层 - 箭头函数没有自己的
arguments
数组,只有词法arguments
,继承自父层 - 箭头函数也没有
super
- 箭头函数也没有
new.target
作用域和作用域链
一定要记住箭头函数的特点,在适当的地方使用。
如果是写对象的方法,要使用普通函数,因为普通函数中有this
,一般情况下指向该对象,而箭头函数没有this,则访问不到对象的其他属性了。
如果返回值是一个简单的表达式,且这个函数内部没有this
的引用,且没有自身引用(递归、绑定/解绑定,且不会要求函数执行这些,可以使用箭头函数。
如果函数内部有很多语句,还是要用普通函数,保证可读性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。