介绍
使用箭头=>定义的函数,称为箭头函数。相比于常规函数的写法,箭头函数的写法更加简洁。箭头函数的设计初衷是要实现类似纯函数的效果,而要实现这样的效果,就必须剔除外部状态,所以在定义一个箭头函数的时候,普通函数常见的this/arguments/caller等会造成副作用的属性是统统没有的。
- 箭头函数只能用赋值式写法,不能用声明式写法
1 | const test = (name) => { |
- 如果参数只有一个,可以不加括号,如果没有参数或者参数多于一个就需要加括号
1 | const test = name => { |
- 如果函数体只有一句话,可以不加花括号
1 | const test = name => console.log(name) |
- 如果函数体没有括号,可以不写return,箭头函数会帮你return
1 | const add = (p1, p2) => p1 + p2 |
箭头函数的特性
箭头函数中没有自己的this,箭头函数中使用的this是通过查找作用域链来确定的,通过call、apply和bind只能传递参数,无法指定this
在没有箭头函数之前,函数作用域经常要将一个this绑定要函数上,通常使用self=this
、call、apply或者bind。在es6中就可以利用箭头函数的这个特性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33// 在es5的时代,我们通常这样做
var Ball = function (x, y) {
this.x = x;
this.y = y;
// 指定self为外层作用域的this
var self = this;
setInterval(function () {
self.x += 10;
self.y += 10;
console.log(self.x, self.y);
}, 1000);
};
new Ball( 0, 0 );
// 10 10 // 1s
// 20 20 // 2s
// 30 30 // 3s
// ...
// 用箭头函数重写
var Ball = function (x, y) {
this.x = x;
this.y = y;
setInterval(()=>{
this.x += 10;
this.y += 10;
console.log(this.x, this.y);
}, 1000);
};
new Ball( 0, 0 );
// 10 10 // 1s
// 20 20 // 2s
// 30 30 // 3s
// ...没有自己的arguments,箭头函数中使用arguments是通过查找作用域链来确定的,如果需要访问箭头函数中的所有参数,可以通过rest参数的方式
1
2
3
4
5
6
7
8
9function f() {
var a = (...rest)=>{
console.log([...arguments]);
console.log(rest);
};
a(10,122,23);
}
f(1,2,3);不能作为构造函数,即无法使用new关键字调用,所以也没有 new.target 属性
- 没有自己的super,,箭头函数中使用的super是通过查找作用域链来确定的
- 没有prototype属性
1
2
3
4const test = name => {
console.log(name)
}
console.log(test); // undefined
箭头函数不能滥用
对于一下情境,箭头函数是不适用的:
- 定义对象原型属性的时候,使用箭头函数,会使this的指向飞到外太空
- 动态this的时候,比如绑定dom事件,dom事件处理函数的this是根据不同的事件源来生成的,这个时候this是动态的,如果使用箭头函数,会绑定静态上下文,造成使用上的问题
- 对象字面量
1
2
3
4
5let a = {
foo: 1,
bar: () => console.log(this.foo)
}
a.bar() //undefined
以上代码中的a
并不能构成作用域,所以查找this的时候,会到全局作用域去搜索,所以this会指向window(global)
总结
完!