部分内容翻译自:文章
=>
箭头符号已经是比较常用的一个符号之一,而它与function
生成的函数比较有一定的差别,这篇文章来总结一下。
箭头函数(Arrow Functions)
箭头函数的诞生为了简化函数的作用域并且让this
使用得更加直观。
this
在=>
函数里的指向
在谈得更深入之前,我们需要有一个很清晰的认知关于this
是如何绑定ES5代码的。
如果this
是在一个object
的方法里面(一个属于一个object
的function
),那么它的指向是哪里呢?
1 | const bunny = { |
没错!它会指向当前的object
。后面会解释为什么。
再来,如果this
在方法里的函数里面呢?1
2
3
4
5
6
7
8
9
10
11
12
13
14const bunny = {
name: 'Usagei',
task: ['transform', 'eat cake', 'blow kisses'],
showTasks: function () {
this.tasks.forEach(function(task) {
alert(this.name + " want to " + task)
})
}
}
bunny.showTasks()
// [object Window] wants to transform
// [object Window] wants to eat cake
// [object Window] wants to blow kisses
可以看到,方法内的函数体中的this
并没有指向object
本身,而是指向了全局作用域,在这里也就是我们的window
对象(如果在node.js的话是global
对象)
为什么this
会绑定到了window
object呢?因为this
总是会指向它所在函数的所有者,在这个case里面,因为它超出了作用域
当它在object
的一个方法体内,这个方法的拥有者是对象,所以this
指向的是object
。但是在这个方法里面再内嵌一个函数,不管是独立定义还是调用其他函数,它总是会指向window
/global
对象。
译者理解:可以看到,forEach中的function其实是无依无靠的,相当于一个匿名函数,因此它挂靠的就是window
/global
1 | const standAloneFunc = function () { |
为什么呢?!
这里也被许多开发者所诟病,因此需要ES6箭头函数来补救。
再继续讲之前,先来看看ES5中是怎么补救的。
#1 使用中间变量来保存this
1 | const bunny = { |
#2 使用bind
函数1
2
3
4
5
6
7
8
9
10
11
12
13
14const bunny = {
name: 'Usagi',
tasks: ['transform', 'eat cake', 'blow kisses'],
showTasks: function() {
this.tasks.forEach(function(task) {
alert(this.name + " wants to " + task);
}.bind(this))
}
}
bunny.showTasks()
// Usagi wants to transform
// Usagi wants to eat cake
// Usagi wants to blow kisses
然后隆重介绍箭头函数:
1 | const bunny = { |
ES5函数中的this
指向的是函数父级所在的作用域,而ES6中,箭头函数中的this
指向的是当前所在的作用域,不会再更上一层。