参考
JavaScript-ES6中的箭头函数(Arrow Function)
一、实例
可以在https://www.tslang.cn/点击 练习观察ES6的箭头函数和ES5之间的对应。
1.当你只需要一个只有一个参数的简单函数时,可以使用新标准中的箭头函数,它的语法非常简单:标识符=>表达式。你无需输入function和return,一些小括号、大括号以及分号也可以省略。
// ES5
var selected = allJobs.filter(function (job) {
return job.isSelected();
});
// ES6
var selected = allJobs.filter(job => job.isSelected());
2.如果要写一个接受多重参数(也可能没有参数,或者是不定参数、默认参数、参数解构)的函数,你需要用小括号包裹参数list。
// ES5
var total = values.reduce(function (a, b) {
return a + b;
}, 0);
// ES6
var total = values.reduce((a, b) => a + b, 0);
3.那么不是非常函数化的情况又如何呢?除表达式外,箭头函数还可以包含一个块语句。回想一下我们之前的示例:
// ES5
$("#confetti-btn").click(function (event) {
playTrumpet();
fireConfettiCannon();
});
// ES6
$("#confetti-btn").click(event => {
playTrumpet();
fireConfettiCannon();
});
注意,使用了块语句的箭头函数不会自动返回值,你需要使用return语句将所需值返回。
二、新的箭头函数的语法,不止是语法上的简便,还解决了this的指向问题
1.让我们假设我们有一个对象有一个叫做sayLater的函数
let obj = {
name: "asim",
sayLater: function() {
console.log(`${this.name}`);
}
};
obj.sayLater();
在sayLater函数中,这个this的指向是obj,所以console.log的值为asim.现在让我们来试一下用setTimeout函数输出的值是多少
let obj = {
name: "asim",
sayLater: function () {
setTimeout(function () {
console.log(`${this.name}`);
}, 1000);
}
};
obj.sayLater();
但是上面输出的值确实undefined
2.调用上下文
这个结果取决于这个函数的调用方式.在最基本的调用上obj.sayLater(),这个值是调用上下文,值为obj.那在setTimeout的匿名函数中呢?this会指向什么呢?
setTimeout(function () {
console.log(`${this.name}`);
}, 1000);
他的答案就看情况了,在浏览器中,值是undefined或者是global对象,这个取决于是使用'use strict'或者非严格模式下,在node中他是一个超时对象。所以在setTimeout的例子中,this的值不会是obj,所以最后this.name返回的要么就是undefined或者是报错了。这样不稳定的语法是个头疼的问题,也是javascript一直存在的问题,在es5中有很多方法解决这个问题,但是一般比较常用的方法就是,在调用上面声明个变量,一般叫做self或者vm,然后把这个用在函数中
let obj = {
name: "asim",
sayLater: function () {
let self = this; // Assign to self
console.log(self);
setTimeout(function () {
console.log(`${self.name}`); // Use self not this
}, 1000);
}
};
但是在es6中,我们有更好的方式解决这个问题,如果我们使用箭头函数,那箭头函数里面的this的值和外面的值是一样的
let obj = {
name: "asim",
sayLater: function () {
console.log(this); // `this` points to obj
setTimeout(() => {
console.log(this); // `this` points to obj
console.log(`${this.name}`); // `this` points to obj
}, 1000);
}
};
obj.sayLater();
可以尝试着跑以上的代码,就发现this输出来的都是obj
再看一个例子
var foo = {
arr:[1,2,3],
sum:0,
testA:function(){
this.arr.forEach(function(x){
this.sum += x;//这里的this指向的不是foo
});
alert(this.sum);//0
},
testB:function(){
this.arr.forEach(x => this.sum+=x);//this指向的是foo
alert(this.sum);//6
}
};
foo.testA();
foo.testB();