首先,我们先来看一下与普通函数相比箭头函数是什么样子:
普通函数:
function foo(x,y){
return x+y;
}
箭头函数:
var foo = (x,y) => x+y;
通过上面简单的例子,我们可以看到箭头函数定义包括
- 一个参数列表,参数列表可以包含零个或多个参数,如果参数的个数不是一个的话要用(..)包围起来。
- 然后是=>。
- 函数体放在最后。
所以,在前面的箭头函数中,箭头函数就是(x,y) => x+y这一部分,然后这个函数引用被赋给变量foo。
只有在函数体的表达式个数大于1个,或者函数体包含非表达式语句的时候才需要用{..}包围。如果只有一个表达式,并且省略了包围的{..}的话,则意味着表达式前面省略了return。
关于箭头函数,我们还应该明白
- 箭头函数是函数表达式,并不存在箭头函数声明。
- 箭头函数不只是更短的语法,而是this。接下来我们来了解一下箭头函数的this。
箭头函数this的指向与普通函数的this指向是完全不同的(关于普通函数的this,可以参考我的这篇文章https://blog.youkuaiyun.com/weixin_38858002/article/details/79372894)。在箭头函数中是不存在函数本身的this的,所以导致箭头函数内部的this就是外层this,同时也就导致箭头函数不能用做构造函数。
关于this的具体用法我们通过下面的一个例子来了解一下:
var obj = {
foo: function(){
var that = this;
btn.addEventListener('click',function(){
that.foo(..)
},true);
}
}
当我我们点击一个按钮想要触发一个函数时,如果使用普通函数,我们就需要先将this保存起来。因为如果不提前保存起来,this就会指向调用它的这个对象,也就是这个按钮。但是如果我们使用箭头函数的话就不用这么麻烦了。
var obj = {
foo: function(){
btn.addEventListener('click',()=>{
this.foo(...);
},true);
}
}
但并不是说所有的情况下我们都可以这样做的,比如下面这个例子:
var obj = {
foo: ()=>{
this.bar(..);
},
bar: ()=>{
...
}
}
obj.foo();
尽管我们以obj.foo()的形式调用,但是this的引用还是会失败。因为在这段代码中,this.bar(..)中的this是外层函数的this,在这里也就是全局对象的this,这与我们想要达到的效果是相背的。
除了this,箭头函数也没有自己的argument,同样是继承外层的。
最后来总结一下使用箭头函数的情况:
- 如果你有一个简短额函数表达式,其中唯一的语句就是return某个值,且这个函数内部没有this引用,且没有自身引用,且不会要求函数执行这些,那么久安全的把它重构为箭头函数。
- 如果你有一个内层函数表达式,依赖于在包含它的函数中调用var that = this或.bind(this)来确保适当的this绑定,那么这个内层函数表达式就可以安全的转为箭头函数。
- 如果你的内层函数表达式依赖于封装函数中某种像 var args =
Array.prototype.slice.call(arguments)来保证arguments,那么这个内层函数就可以安全的转为箭头函数。