让前端飞Web前端之路前端开发那些事

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

2018-06-14  本文已影响198人  RichardBillion

首先不得不承认,箭头函数是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:

阅读原文

上一篇下一篇

猜你喜欢

热点阅读