1. 什么是箭头函数?
ES6以前创建一个函数有两种方式:
- 函数声明
function fn(params) { // 函数声明会提升
return params;
}
- 函数表达式
var fn = function(params) { // 函数表达式不提升
return params;
}
ES6简化了函数的创建:
const fn = params => params; // 等价于函数表达式创建一个函数
我们再来个复杂的:
// ES5
function father(a) {
return function(b) {
return {son: 'Tony Stark'}
}
}
// ES6箭头函数
const father = a=> b=> ({son: 'Tony Stark'}); // 如果返回的是一个对象,需要用小括号包起来
2. 箭头函数解决了什么问题?
箭头函数解决了ES5中的this指向问题(this永远指向调用方),在很多场景下,我们需要声明一个变量存储this指针或者使用bind、apply、call方法改变this指向。
在ES6中,箭头函数可以优化这种场景下的编码方式。因为箭头函数没有this指向,他会向上层作用域查找,直到最顶层的global或者window。
var obj = {
a: 1,
b: function() {
setTimeout(function(){
console.log(this.a);
}, 1000)
}
}
obj.b(); // 输出undefined,因为此时的this指向的是window,window下没有变量a
解决这个this指向问题,有两种方法:
- 声明一个变量存储this
//...todo
var _this = this;
setTimeout(function(){
console.log(_this.a);
}, 1000)
- 使用bind方法绑定this
//...todo
setTimeout(function(){
console.log(this.a);
}.bind(this), 1000)
很显然这两种方式都不是我们想要的,那么,我们使用箭头函数来解决这个问题:
// ...todo
setTimeout(()=>{
console.log(this.a);
}, 1000)
3. 箭头函数中不光没有this,也没有arguments
const fn = ()=> {
console.log(arguments);
}
fn(1,2,3,4,5); // ReferenceError: arguments is not defined
虽然没有arguments,但是我们可以用rest操作符(获取函数的多余参数)拿到函数的参数。而且拿到的函数的参数是一个数组。而不是像arguments那样的类数组,还需要通过Array.prototype.slice.call(arguments)或者Array.from(arguments)的方式转换arguments。
const fn = (...args)=> {
console.log(args);
}
fn(1,2,3,4,5); // [1,2,3,4,5]
4. 总结
以上主要阐述了箭头函数最常见的3个点,包括:
- 箭头函数的语法
- 箭头函数的this指向
- 箭头函数的arguments
其实箭头函数还有一些其他注意事项:比如不能作为构造函数,不可以使用yield命令,具体可以去阅读阮一峰老师的ES6标准入门-函数的扩展