重新捋一捋ES6箭头函数

192 阅读2分钟

1. 什么是箭头函数?

ES6以前创建一个函数有两种方式:

  1. 函数声明
function fn(params) { // 函数声明会提升
    return params;
}
  1. 函数表达式
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指向问题,有两种方法:

  1. 声明一个变量存储this
//...todo
var _this = this;
setTimeout(function(){
    console.log(_this.a);
}, 1000)

  1. 使用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个点,包括:

  1. 箭头函数的语法
  2. 箭头函数的this指向
  3. 箭头函数的arguments

其实箭头函数还有一些其他注意事项:比如不能作为构造函数,不可以使用yield命令,具体可以去阅读阮一峰老师的ES6标准入门-函数的扩展