xfshen

导航

《理解 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;
};

 

posted on 2016-10-22 11:15  xfshen  阅读(344)  评论(0编辑  收藏  举报