《理解 ES6》阅读整理:函数(Functions)(四)Arrow Functions
箭头函数(Arrow Functions)
就像名字所说那样,箭头函数使用箭头(=>)来定义函数。与传统函数相比,箭头函数在多个地方表现不一样。
箭头函数语法(Arrow Function Syntax)
箭头函数有多种实现方法。比如你想实现一个只有一个参数并且直接返回此参数值的函数:
let reflect = value => value; //相当于下面的函数 let reflect = function(value) { return value; };
上面的例子中,函数只有一个参数,所以用不用()都是可以的。如果你的参数包含多个,就需要用()包住参数了:
let sum = (num1, num2) => num1 + num2; //相当于下面的函数 let sum = function(num1, num2) { return num1 + num2; };
另外如果函数没有参数,()也是必须的:
let getName = () => "Zakas"; //相当于下面的函数 let getName = function() { return "Zakas"; };
如果函数体内包含多个表达式,那么就需要用{}包围住函数体了:
let sum = (num1, num2) => { num1 = num1 + 3; return num1 + num2; }; //相当于下面的函数 let sum = function(num1, num2) { num1 = num1 + 3; return num1 + num2; };
其实可以看到,箭头函数可以直接按照(参数)=> {函数体}的方式来写就可以了。上面的例子只是为了说箭头函数在某些情况下可以简写。
那么除了语法外,箭头函数与传统函数相比,有哪些不一样呢?
1、没有this、super、argument和new.target绑定
this、super、argument和new.target的值由最内层包含箭头函数的非箭头函数决定。首先来看arugments绑定:
function outer(num1, num2) { return function () { return arguments[0]; } } let inner = outer(1, 2); console.log(inner(3)); // 3 ---------------------------------------------------------- function outer(num1, num2) { return () => { return arguments[0]; } } let inner = outer(1, 2); console.log(inner(3)); // 1
箭头函数本身没有arguments对象,实际上访问的是外层的outer函数的arguments对象,所以输出1。 不过在箭头函数中可以使用剩余参数访问函数的参数。
在JavaScript中,this绑定是一个比较复杂的机制,因为this具体指向的值要到实际执行时才能决定,并不一定是定义时所指向的值。在箭头函数中没有this绑定,其实就是指this的值在函数定义时就已经确定了,并不会在实际执行时改变值。来看一个例子:
function foo() { return () => { return this.a; } } var obj1 = {a: 2}; var obj2 = {a: 3}; var bar = foo.call(obj1); console.log(bar.call(obj2)); // 2
上面的代码中,bar在创建时,this被绑定到obj1上,然后在执行时,this的值不会被重新绑定到obj2,因此输出2。如果里面的函数是传统函数,那么输出3。
new.target和super都是ES6引入的标准,在后面会进行说明。
2、没有prototype,不能被new调用
let foo = () => {}; console.log(foo.prototype); // undefined let obj = new foo(); // TypeError: foo is not a constructor
3、不允许重复命名的参数
不管是strict模式还是not-strict模式,箭头函数都不允许重复命名的参数:
let sum = (num1, num2, num1) => { // SyntaxError: Duplicate parameter name not allowed in this context num1 = num1 + 3; return num1 + num2; };