美文网首页让前端飞Web前端之路前端开发那些事
【翻译】你知道何时使用或者不使用ES6箭头函数吗?

【翻译】你知道何时使用或者不使用ES6箭头函数吗?

作者: RichardBillion | 来源:发表于2018-06-14 22:28 被阅读198次

    首先不得不承认,箭头函数是ES6中非常受欢迎的一个功能,它提出了一种新的书写方式来简洁的定义函数。

    举例说明:

    ES5:

    function timesTwo(params) {
      return params * 2;
    }
    
    timesTwo(4); //8
    

    使用ES6箭头函数:

    const timesTwo = params => params * 2;
    
    timesTwo(4); //8
    

    代码更简短,而且可以省略大括号和return语句(在没有代码块的情况下)。与ES5相比,为何箭头函数的表现方式可以有如此大的不同呢?

    各种变量

    你可能见过箭头函数有很多种的使用方式,比如:

    1. 没有参数

    如果没有参数,可以在=>之前放置一个空括号

    const a = () => 42
    a() //42
    

    实际上, 我们甚至不需要括号:

    const a = _ => 42
    a() //42
    
    1. 一个参数

    在这种情况下,括号是可选的:

    const a = x => 42 || const a = (x) => 42
    a() || a(1) //42
    
    1. 多个参数

    此时,必须加括号:

    const a = (x, y) => 42
    a(1, 2) //42
    
    1. 语句(而非表达式)

    在最基本的形式中,表达式会产生一个值,而语句代表着一种待执行的行为,比如if else语句。使用箭头函数时,语句必须有大括号。而一旦使用了花括号,就必须添加return 关键字。

    在箭头函数中使用if语句的例子:

    var feedTheCat = (cat) => {
      if (cat === 'hungry') {
        return 'Feed the cat';
      } else {
        return 'Do not feed the cat';
      }
    }
    
    1. 代码块

    如果你的代码在一个块中,就必须显式的使用return语句。

    var addValues = (x, y) => {
      return x + y
    }
    
    1. 对象字面量

    如果需要返回一个对象,就要使用()包裹。这会迫使解释器去评估括号内的内容,能够正确的返回对象。

    const obj = x =>({ y: x })
    obj(1) //{y: 1}
    

    匿名语法

    箭头函数是匿名的,这会带来一些问题:

    1. 难以debug

    出现错误时,无法追踪该方法名称或具体的执行行号(个人不是很认同,箭头函数相当于匿名函数,将其地址赋值给变量后不是一样的使用么)

    1. 没有自引用

    如果你需要自引用(比如递归),使用箭头函数难以实现。

    主要的优点: 不用显式绑定this

    在函数表达式中,this是根据它被调用的上线文绑定到不同的值的,但是在箭头函数中,this是直接被绑定到词法作用域的。this 就是指向包含着箭头函数的这段代码。

    举个栗子:

    //ES5
    var obj = {
      id: 42,
      counter: function counter() {
        setTimeout(function() {
          console.log(this.id);
        }.bind(this), 1000);
      }
    };
    

    在上段代码中,bind(this)不能省略,否则this将指向window,从而this.id打印出undefined.

    //ES6
    var obj = {
      id: 42,
      counter: function counter() {
        setTimeout(() => {
          console.log(this.id);
        }, 1000);
      }
    };
    

    箭头函数不能绑定到this关键字,所以它会在词法上上升一个作用域,然后在定义的作用域中使用这个值。

    何时不该使用箭头函数?

    经过上边几个例子,应该也能意识到箭头函数并不能完全替代常规的函数。那么何时我们不该使用箭头函数呢?

    1. 对象方法
    var cat = {
      lives: 9,
      jumps: () => {
        this.lives--;
      }
    }
    

    调用cat.jumps()后,cat.lives并不会减1。这是因为this就没有被绑定到这个对象上,而是从父级作用域继承了this.

    1. 具有动态context的回调函数

    当context需要动态改变的时候,箭头函数通常不是正确的选择。比如在一个事件句柄中:

    var button = document.getElementById('press');
    button.addEventListener('click', () => {
      this.classList.toggle('on');
    });
    

    如果我们点击按钮,我们会得到一个TypeError。这是因为this不是绑定到按钮,而是绑定到了它的父级。

    1. 当使用箭头函数使你的代码可读性降低(难以知道这段代码将发生什么)的时候

    何时使用箭头函数?

    箭头函数最能发挥功力的场景就是需要this绑定到context,而非函数本身的时候。我还尤其喜欢在map或者reduce方法中使用箭头函数,这使得程序可读性更强。

    Reference:

    阅读原文

    相关文章

      网友评论

        本文标题:【翻译】你知道何时使用或者不使用ES6箭头函数吗?

        本文链接:https://www.haomeiwen.com/subject/kwrseftx.html