[译]JavaScript ES6箭头函数指南

前言

胖箭头函数(Fat arrow functions),又称箭头函数,是一个来自ECMAScript 2015(又称ES6)的全新特性。有传闻说,箭头函数的语法=>,是受到了CoffeeScript 的影响,而且它与CoffeeScript中的=>语法同样,共享this上下文。javascript

箭头函数的产生,主要由两个目的:更简洁的语法和与父做用域共享关键字this。接下来,让咱们来看几个详细的例子。java

新的函数语法

传统的JavaScript函数语法并无提供任何的灵活性,每一次你须要定义一个函数时,你都必须输入function () {}CoffeeScript现在之因此那么火,有一个不可忽略的缘由就是它有更简洁的函数语法。更简洁的函数语法在有大量回调函数的场景下好处特别明显,让咱们从一个Promise链的例子看起:es6

function getVerifiedToken(selector) {
  return getUsers(selector)
    .then(function (users) { return users[0]; })
    .then(verifyUser)
    .then(function (user, verifiedToken) { return verifiedToken; })
    .catch(function (err) { log(err.stack); });
}

如下是使用新的箭头函数语法进行重构后的代码:编程

function getVerifiedToken(selector) {
  return getUsers(selector)
    .then(users => users[0])
    .then(verifyUser)
    .then((user, verifiedToken) => verifiedToken)
    .catch(err => log(err.stack));
}

如下是值得注意的几个要点:数组

  • function{}都消失了,全部的回调函数都只出如今了一行里。编程语言

  • 当只有一个参数时,()也消失了(rest参数是一个例外,如(...args) => ...)。函数

  • {}消失后,return关键字也跟着消失了。单行的箭头函数会提供一个隐式的return(这样的函数在其余编程语言中常被成为lamda函数)。oop

这里再着重强调一下上述的最后一个要求。仅仅当箭头函数为单行的形式时,才会出现隐式的return。当箭头函数伴随着{}被声明,那么即便它是单行的,它也不会有隐式returnthis

const getVerifiedToken = selector => {
  return getUsers()
    .then(users => users[0])
    .then(verifyUser)
    .then((user, verifiedToken) => verifiedToken)
    .catch(err => log(err.stack));
}

若是咱们的函数内只有一条声明(statement),咱们能够不写{},这样看上去会和CoffeeScript中的函数很是类似:rest

const getVerifiedToken = selector =>
  getUsers()
    .then(users => users[0])
    .then(verifyUser)
    .then((user, verifiedToken) => verifiedToken)
    .catch(err => log(err.stack));

你没有看错,以上的例子是彻底合法的ES6语法。当咱们谈论只包含一条声明(statement)的箭头函数时,这并不意味着这条声明不可以分红多行写。

这里有一个坑,当忽略了{}后,咱们该怎么返回空对象({})呢?

const emptyObject = () => {};
emptyObject(); // ?

不幸的是,空对象{}和空白函数代码块{}长得如出一辙。。以上的例子中,emptyObject{}会被解释为一个空白函数代码块,因此emptyObject()会返回undefined。若是要在箭头函数中明确地返回一个空对象,则你不得不将{}包含在一对圆括号中(({})):

const emptyObject = () => ({});
emptyObject(); // {}

下面是一个更完整的例子:

function () { return 1; }
() => { return 1; }
() => 1
 
function (a) { return a * 2; }
(a) => { return a * 2; }
(a) => a * 2
a => a * 2
 
function (a, b) { return a * b; }
(a, b) => { return a * b; }
(a, b) => a * b
 
function () { return arguments[0]; }
(...args) => args[0]
 
() => {} // undefined
() => ({}) // {}

this

JavaScriptthis的故事已是很是古老了,每个函数都有本身的上下文。如下例子的目的是使用jQuery来展现一个每秒都会更新的时钟:

$('.current-time').each(function () {
  setInterval(function () {
    $(this).text(Date.now());
  }, 1000);
});

当尝试在setInterval的回调中使用this来引用DOM元素时,很不幸,咱们获得的只是一个属于回调函数自身上下文的this。一个一般的解决办法是定义一个that或者self变量:

$('.current-time').each(function () {
  var self = this;
 
  setInterval(function () {
    $(self).text(Date.now());
  }, 1000);
});

但当使用胖箭头函数时,这个问题就不复存在了。由于它不产生属于它本身上下文的this

$('.current-time').each(function () {
  setInterval(() => $(this).text(Date.now()), 1000);
});

arguments变量

箭头函数与普通函数还有一个区别就是,它没有本身的arguments变量:

function log(msg) {
  const print = () => console.log(arguments[0]);
  print(`LOG: ${msg}`);
}
 
log('hello'); // hello

再次重申,箭头函数没有属于本身的thisarguments。可是,你仍能够经过rest参数,来获得全部传入的参数数组:

function log(msg) {
  const print = (...args) => console.log(args[0]);
  print(`LOG: ${msg}`);
}
 
log('hello'); // LOG: hello

关于yield

箭头函数不能做为generator函数使用。

最后

箭头函数是我最喜欢的ES6特性之一。使用=>来代替function是很是便捷的。但我也曾见过只使用=>来声明函数的代码,我并不认为这是好的作法,由于=>也提供了它区别于传统function,其所独有的特性。我我的推荐,仅在你须要使用它提供的新特性时,才使用它:

  • 当只有一条声明(statement)语句时,隐式return

  • 须要使用到父做用域中的this

原文连接

https://strongloop.com/strongblog/an-introduction-to-javascript-es6-arrow-functions/

相关文章
相关标签/搜索