简介

Arraw function expression 比function有更简介的语法,它不绑定自己的this,arguments,super,new.target,最适合用作非方法的函数,不能够用做构造函数。接下来介绍一些特性。

更简洁的语法

  1. 当arrow function只有一个参数的时候可以不写包裹参数括号。
  2. 不需要明确返回return。
1
2
3
4
5
6
7
8
var materials = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
materials.map(material => material.length); // [8, 6, 7, 9]

不绑定this

先看一个绑定this的例子:

1
2
3
4
5
6
7
8
function Person() {
this.age = 0;
setInterval(function growUp() {
this.age++;
}, 1000);
}
var p = new Person();

p.age结果是0。growUp()函数调用后会搜索this,setInterval中没有this.age,那么this指向全局对象,默认为0。

arrow function的this会使用上下文中包含arrow function的外部作用域的this。

1
2
3
4
5
6
function Person() {
this.age = 0;
setInterval(() => {
this.age++;
}, 1000);
}

p.age结果每隔一秒会增长一位。

使用call或者apply调用arrow function的时候,绑定的this被忽略。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var adder = {
base: 1,
add: function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base: 2
};
return f.call(b, a);
}
};
console.log(adder.add(1)); // This would log to 2
console.log(adder.addThruCall(1)); // This would log to 2 still

不绑定arguments

如果外部执行环境中有arguments对象,那么在arrow function中访问arguments对象的时候会是外部环境的arguments对象。如果外部执行环境中没有arguments对象,那么在arrow funciton中访问arguments对象的时候会报错。

1
2
3
4
5
6
var arguments = [1, 2, 3];
var arr = () => arguments[0];
arr(); // 1
var foo = () => arguments[0]
foo(); // arguments is not defined

如果想在arrow function中使用类似arguments的对象,那么可以使用ES6中的spead operator。

1
2
3
4
5
6
function foo(n) {
var f = (...args) => args[0] + n;
return f(10);
}
foo(1); // 11

用作非方法函数

1
2
3
4
5
6
7
8
9
10
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}
obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}

不用作构造函数

1
2
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

Arrow function 没有prototype property

1
2
var Foo = () => {};
console.log(Foo.prototype); // undefined

返回字面对象

1
2
3
4
5
6
返回字面对象时使用简明语法不会工作。
var func = () => { foo: 1 };
这是因为在({})中的代码会被解析为连续的语句(foo会被解析为标签,而不是key)。
记住要在字面对象外面加一层括号。
var func = () => ({foo: 1});