三、ES6系列之箭头函数
ES6 增加了箭头函数,箭头函数表达式的语法比函数表达式更简洁,并且没有自己的 this,arguments,super 或 new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
基础语法
1 | var func = (value, label) => { |
高级语法
1 | //加括号的函数体返回对象字面量表达式: |
没有 this
箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值。
this 的绑定一直是一个比较头疼的问题,请看下面的列子:
1 | var age = 0; |
上面这个例子中 p.age 的值一直都是 0,增加的是全局中 age 的值,因为函数 ageUp 中的 this 指向全局 window ,在 ECMAScript 3/5 中,通过将 this 值分配给封闭的变量,可以解决 this 问题。
1 | var age = 0; |
或者,可以创建绑定函数,以便将预先分配的 this 值传递到绑定的目标函数(上述示例中的 growUp()函数)。
1 | var age = 0; |
箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this。因此,在下面的代码中,传递给 setInterval 的函数内的 this 与封闭函数中的 this 值相同:
1 | function Person() { |
最后,因为箭头函数没有 this,所以也不能用 call()、apply()、bind() 这些方法改变 this 的指向,可以看一个例子:
1 | var value = 1; |
没有 arguments
箭头函数没有自己的 arguments 对象,所以箭头函数可以访问外围函数的 arguments 对象:
1 | function constant() { |
在大多数情况下,使用剩余参数是相较使用 arguments 对象的更好选择。
1 | let foo = (...args) => args; |
不能使用 new 操作符
JavaScript 函数有两个内部方法:[[Call]] 和 [[Construct]]。
当通过 new 调用函数时,执行 [[Construct]] 方法,创建一个实例对象,然后再执行函数体,将 this 绑定到实例上。
当直接调用的时候,执行 [[Call]] 方法,直接执行函数体。
箭头函数并没有 [[Construct]] 方法,不能用作构造函数,和 new 一起用会抛出错误。
1 | var Foo = () => {}; |
没有 prototype
箭头函数没有 prototype 属性。
1 | var Foo = () => {}; |
没有 new.target
因为不能使用 new 调用,所以也没有 new.target 值。
没有 super
连原型都没有,自然也不能通过 super 来访问原型的属性,所以箭头函数也是没有 super 的,不过跟 this、arguments、new.target 一样,这些值由外围最近一层非箭头函数决定。