Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[译]你应该在何时避免使用箭头函数? #12

Open
rico-c opened this issue Dec 10, 2018 · 1 comment
Open

[译]你应该在何时避免使用箭头函数? #12

rico-c opened this issue Dec 10, 2018 · 1 comment
Labels

Comments

@rico-c
Copy link
Owner

rico-c commented Dec 10, 2018

[译]你应该在何时避免使用箭头函数?

原文地址:https://medium.freecodecamp.org/when-and-why-you-should-use-es6-arrow-functions-and-when-you-shouldnt-3d851d7f0b26

原文日期:2018.6.6
译者:RicardoCao

箭头函数与ES5 function的差异

首先我们会发现箭头函数有非常多可以使用的句法,我们一起看看下面的例子:

1. 无参数

在没有参数的情况下,可以直接在 =>前放置一个圆括号()

() => 42

甚至连括号都不需要

_ => 42

2. 单个参数

在单个参数情况下,圆括号是可选的:

x => 42  || (x) => 42

3. 多个参数

在多个参数情况下,圆括号是必须的:

(x, y) => 42

4. 函数语句

在箭头函数中,如果代码语句多于一条,就需要使用花括号包裹函数语句 ,而一旦你使用了花括号,你也需要在箭头函数中使用return返回对应的返回值。

这里有一个使用箭头函数的例子:

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

5. 输出对象

如果想返回一个对象,则需要用圆括号将对象包裹起来,这可以强制编译器解析圆括号中的内容并返回,而不是将花括号内当做函数语句。

x =>({ y: x })

匿名句法

我们需要注意到箭头函数是匿名的,这也意味着他们是没有函数名的,这也造成了一些问题:

1. 更难调试

当我们遇到BUG时,将不能根据函数名或发生异常的行数来定位异常函数的位置。

2. 无法调用自身

如果你需要在使用箭头函数中递归调用自身,那么你会发现这在箭头函数中是行不通的。

无绑定this

在ES6之前的函数this关键字指向会根据函数被调用的上下文环境决定。但是在箭头函数中,this在函数定义时绑定,这意味着箭头函数使用包裹箭头函数的外部代码中的this

举个栗子,我们看下面的setTimeout方法:

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

在ES5的例子中,.bind(this)用来绑定this上下文,如果不使用bind的话,默认this将会是undefined

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

箭头函数无法绑定this关键字,所以它会自动向上一层作用域寻找this,并使用上一层的this

在何时应该避免使用箭头函数?

在一下几个情景你也许应该避免使用箭头函数:

1. 对象中的方法

当你调用cat.jumps,lives的数量并不会减少,这是因为this没有被绑定在cat对象上,而是使用父作用域的this

var cat = {
  lives: 9,
  jumps: () => {
    this.lives--;
  }
}

运行结果:
image

2. 动态上下文的回调函数

如果是在动态上下文的回调中,箭头函数是不适用的,下面看一下栗子:

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

这时点击按钮,会报错TypeError,这是因为this没有被绑定到按钮上。

3. 当箭头函数使你的代码可读性降低时

大量使用箭头函数,可能会对理解函数的含义造成障碍,这时可以考虑使用ES5函数增强可读性。

4. 用作构造函数时

箭头函数不可以作为构造函数,不可以使用new命令,否则会抛出一个错误。

@rico-c rico-c added the 翻译 label Dec 10, 2018
@whh2017
Copy link

whh2017 commented Dec 11, 2018

Good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants