【笔记】ES6语法-箭头函数

221 阅读3分钟

箭头函数的特点

  ①写起来简单;
  ②可以解决this的问题。
  箭头函数没有function关键字

  高阶函数,是一等公民什么事都能干,函数可以返回函数,函数可以作为参数传给另一个函数,功能强大。
  普通函数,特点是由于js的预解析机制函数一旦声明就在哪里都可以被调用,无论调用在函数声明前还是在之后。
  箭头函数是高阶函数
  下面示范如何将普通函数转化为高阶函数:

// 普通函数
function fn(a){
    return a;
}
// 高阶函数
// 首先高阶函数可以抵抗js预解析机制,所以用let或const声明
// 写入参数的小括号与写入运算的大括号之间用=>连接,因此得名箭头函数
// 参数只有一个时可以省略小括号,当不写return时可以省略大括号
let fn = (a)=>{ return a }
let fn = a =>{ return a }

// 普通函数
function a (x){
    return function (y){
        return x+y;
    }
}
// 高阶函数
// 若返回值为对象,=>后不能直接跟返回值,因为对象的大括号会与箭头函数的大括号表达冲突,需要把对象用小括号括起来
let a = x => y => x+y;
let a = x => y => ({sum: x+y});

箭头函数的this指向

  在普通函数中,我们看this的指向遵循的规律是谁调用就指向谁。

let obj = {
    fn: function(){
        console.log(this);
    }
}
console.log(obj.fn());

  其中一个最经典的this指向问题如下:

let obj = {
    fn: function(){
        setTimeout(function(){
            console.log(this);
        },5000);
    }
}
obj.fn();

  我们通常的需求是这个this指向obj,但此时实际上是setTimeout()在调用函数所以this指向Window。
  我们以前的解决【方法一】是在setTimeout()之前声明一个变量that来储存指向obj的this再将that套入setTimeout()中。
  还有【方法二】是利用bind()(call()会让函数立即执行不等setTimeout(),apply()?)将this绑定给setTimeout()中的函数,函数在setTimeout()调用前先调用了bind(),此时this还是指向obj并且被绑定:

let obj = {
    fn: function(){
        setTimeout(function(){
            console.log(this);
        }.bind(this),5000);
    }
}
obj.fn();

  现在我们可以用ES6箭头函数来更简洁地解决这一问题,因为箭头函数中没有this指向,这时this写在箭头函数里就相当于一个变量,自身作用域内没有的变量函数会向上查询,一旦向上查询便能获取到外面包裹的这个函数的this而这个this指向obj:

let obj = {
    fn: function () {
        setTimeout(() => {
            console.log(this);
        }, 5000)
    }
}
console.log(obj.fn());
【注意】外层的函数不能写成箭头函数,否则this一直向上查询到Window,因为对象不是作用域

剩余运算符 …

  上面我们了解到箭头函数没有this,下面要讲的是箭头函数也没有arguments,因此某些情况下我们需要用到剩余运算符。
  剩余运算符中剩余的意思是除某些参数外剩余的参数都放入数组中。
  在学习箭头函数前我们也有方法实现类似的功能,如下:

function fn1 (){
    [].slice.call(arguments,1);
}
fn1("x",1,2,3,4,5)

  用剩余运算符写:

let fn2 = (x,...args) => {
    console.log(args);
}
fn2("x",6,7,8,9,0)