Fork me on GitHub

ES6箭头函数

第一次见到这箭头=>,我觉得这是很奇葩的写法,因为作为一个老男人来说,会影响阅读和理解代码的速度=_=||

作为ES6新特性之一,箭头函数特点如下

a)简洁
b)this指向
c)rest取代arguments

1. 简洁

1
2
3
var showTips = function(d){
$("#Tip").text(d).show();
}

这段代码换成箭头写法是这样

1
var showTips = (d) => {$("#Tip").text(d).show()};

因为只有一个参数 d 所以括号可以省去,因为function只有一句所以花括号也可以省去,如下

1
var showTips = d => $("#Tip").text(d).show();

但是这2个function并不完全相同,去掉花括号后,其实等价于

1
2
3
var showTips = function(d){
return $("#Tip").text(d).show();
}

也就是带花括号的是原汁原味的code,而省了花括号后会自动加上return,比如做价格运算时

1
2
3
function getTotalPrice(price, count){
return price * count;
}

用箭头函数写法就是

1
var getTotalPrice = (price,count) => price * count;

确实相当简洁

2. this指向

1
2
3
4
5
6
7
function Test(s){
this.dom = $("#Tip");
this.dom.text(s).show();
setTimeout(function(){
this.dom.hide();
},2000);
}

这段代码看起来没大问题,甚至直接执行

1
2
3
所以一般采用闭包或是实例化,例如
```js
var t = new Test("Hi Function");

此时function里的this指向对象 t 本身,但是setTimeout里面的this却指向window,会导致2秒后找不到dom对象
正常做法是setTimeout前var一个变量来保存this

1
2
3
4
5
6
7
8
9
function Test(s){
this.dom = $("#Tip");
this.dom.text(s).show();
var self = this;
setTimeout(function(){
self.dom.hide();
},2000);
}
var t = new Test("Hi Function");

这是比较常见但也比较丑陋的写法,还有一种是这样

1
2
3
4
5
6
7
8
function Test(s){
this.dom = $("#Tip");
this.dom.text(s).show();
setTimeout(function(){
this.dom.hide();
}.bind(this),2000);
}
var t = new Test("Hi Function");

把外面的this强行绑定到里面去,这样里面调用this则会变成调外面
到了ES6箭头函数,this并不会指向函数本身,而且往上层查找this,包括arguments
所以用箭头函数可以这样写

1
2
3
4
5
6
7
8
function Test(s){
this.dom = $("#Tip");
this.dom.text(s).show();
setTimeout( () => {
this.dom.hide();
},2000);
}
var t = new Test("Hi Function");

3. argumengts

如上面说的,箭头函数里arguments会往上层查找arguments,所以下面这个最后输出Hi,而不是Hello

1
2
3
4
5
6
function Test(s){
return (() => {
console.log(arguments)
})("Hello");
}
Test("Hi");

再修改一下多套一层箭头函数

1
2
3
4
5
6
7
8
function Test(s){
return () => {
return (() => {
console.log(arguments)
})("Hello");
}
}
Test("Hi")();

一样打印Hi,因为会顺着作用域链往上查找,套了2个return看着有点乱,换个写法

1
2
3
4
5
6
function Test(s){
setTimeout( () => {
console.log(arguments)
},200);
}
Test(4,5,6); // -> [4,5,6]

如果想用arguments怎么办,可以用ES6新特征rest

1
2
3
4
5
6
7
8
function Test(s){
return (() => {
return (...r) => {
console.log(r)
};
})(1,2,3)
}
Test(4,5,6)(7,8); // -> [7,8]

所以有个面试经常用到的题目,写个计时器每一秒打印个数字,并递增1,就可以不用闭包写法了

1
2
3
4
var i =0;
setInterval( () => {
if(i<10) console.log(i++);
},1000);

相关文章推荐

如果觉得我的文章对您有用,可否请我喝杯速溶咖啡