从对箭头函数深恶痛绝,到我也爱上用它——

526 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

当我第一次在别人的页面中见到箭头函数的回调的时候,我整个人都是:

image.png

但后来学会了之后发现箭头函数他是真好用啊,只要能辨别箭头函数常用的几个形式,你也会爱上它!

怎样辨认出一个箭头函数?

箭头函数不需要function关键字声明,所以我们常常会认不出这个一个箭头函数,一个最标准的箭头函数往往长这样:

let fn = (arg1, arg2, arg3) => {
    return arg1 * arg2 * arg3;
}

它等同于用函数表达式这样表示:

let fn = function(arg1, arg2, arg3){
    return arg1 * arg2 * arg3;
}

主要由三部分组成:

  • 小括号()包含着函数参数
  • =>
  • 大括号 {} 包含着函数体内容

怎样辨认出一个简化的箭头函数

箭头函数常见有两种简化规则:

1. 省略小括号

如果函数的参数只有一个,就可以省略小括号

let fn = arg1 => {
    return arg1 * args;
}

2. 省略花括号

当函数体语句只有一条,而且为返回值时,就可不写花括号,而且注意,此时return关键字也不能写。

let fn = arg1 => arg1*arg1;

看到没,就简化成一行代码就可以表示的东西,辨别箭头函数最重要的是认出=>

既然这么简单,那我函数以后都写成箭头函数的样子可以吗?

不可以,箭头函数的简化带来三点限制:

  1. 不能作为构造函数使用
  2. 不能使用argumens。
    • 还记得argumens吗?他用来保存函数体内部的实参,是一个伪数组。

    • 但是能用rest参数,也就是说,你可以这样写:

      let fn1 = (...args) => {
          console.log(args);
      }
      fn1(1,2,3,4,5); //返回数组[1, 2, 3, 4, 5]
      
  3. 箭头函数中this的指向是静态的,指向声明时所在作用域的this值。
    • 如果定义在全局,this值就永远是windows

    • 如果是回调函数内使用箭头函数,this值指向父级作用域的this值。

    • 也就是说,不能将箭头函数作为对象的方法来使用。为什么?

      • 因为当我们调用对象的方法时,一般的this用在方法内,获取对对象属性的访问。而使用箭头函数定义的方法,其父级作用域是全局作用域,所以this指向仍是windows。可以看下面这个例子:
      const c2 = {
          name: '罗塞尔大帝',
          profession: '日记家',
          sequence: '黑皇帝',
          intro: function () {
              console.log(this);
          },
          intro1: () => {
              console.log(this);
          },
      }
      c2.intro();     
      c2.intro1();
      

      image.png

      可以看到控制台输出的第二个是windows对象。

    • 事件的回调也不应使用箭头函数。

      document.getElementById('box').onclick = () => {
          console.log(this);    //输出windows,因为箭头函数this指向父级作用域(全局)的this
      }
      

什么时候用箭头函数

这时问题出现了,简写成这个鬼样子,而且this的指向还被改了,什么时候能用它?

根据我浅薄的经验,当回调函数与本层作用域的this值无关的时候用,

  1. 定时器
document.getElementById('box').onclick = function(){
    //原本要保存 this 的值
    // let that = this
    // setTimeout(function(){
    //      //改动box标签的背景颜色
    //     that.style.background = 'pink';
    // }, 2000);

    setTimeout(() => {
        //而箭头函数this直接指向外层作用域的this,也就是box标签
        this.style.background = 'pink';
    }, 2000)
}
  1. 数组的方法回调(非常常用)

如数组的filter,map,forEach方法,连mdn里介绍方法用的实例也是用的箭头函数。

image.png

总结一下

见多了箭头函数的用法,就会体验到好处。 箭头函数this的指向一定要搞清楚。