JavaScript ES6箭头函数指南

简介:

前言

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

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

新的函数语法

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

复制代码

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函数)。

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

复制代码

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

复制代码

如果我们的函数内只有一条声明(statement),我们可以不写{},这样看上去会和CoffeeScript中的函数非常相似:

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

JavaScript中this的故事已经是非常古老了,每一个函数都有自己的上下文。以下例子的目的是使用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

再次重申,箭头函数没有属于自己的this和arguments。但是,你仍可以通过rest参数,来得到所有传入的参数数组:

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

关于yield

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


本文转自  zddnd  51CTO博客,原文链接:http://blog.51cto.com/13013666/1940096
相关文章
|
6月前
|
机器学习/深度学习 JavaScript 前端开发
JS进阶教程:递归函数原理与篇例解析
通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
274 19
|
8月前
|
JavaScript
JS实现多条件搜索函数
JS封装的多条件搜索
|
10月前
|
JavaScript 前端开发
JavaWeb JavaScript ③ JS的流程控制和函数
通过本文的详细介绍,您可以深入理解JavaScript的流程控制和函数的使用,进而编写出高效、可维护的代码。
222 32
|
9月前
|
JavaScript 前端开发 网络架构
ES6解构赋值详解;全面掌握:JavaScript解构赋值的终极指南
解构赋值是一个强大且灵活的工具,它使得从数组和对象中提取数据变得更加简单和直观。通过掌握解构赋值的基本语法和实践,你可以写出更加简洁、可读性更强的代码。在实际项目中,解构赋值广泛应用于函数参数处理、变量交换、嵌套结构操作等场景,极大地提升了代码的灵活性和简洁度。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
存储 JavaScript 前端开发
JS的ES6知识点
【10月更文挑战第19天】这只是 ES6 的一些主要知识点,ES6 还带来了许多其他的特性和改进,这些特性使得 JavaScript 更加现代化和强大,为开发者提供了更多的便利和灵活性。
258 58
|
JavaScript 前端开发 安全
ECMAScript 6(以下简称 ES6)的出现为 JavaScript 带来了许多新的特性和改进,其中 let 和 const 是两个非常重要的关键字。
ES6 引入了 `let` 和 `const` 关键字,为 JavaScript 的变量管理带来了革新。`let` 提供了块级作用域和暂存死区特性,避免变量污染,增强代码可读性和安全性;`const` 用于声明不可重新赋值的常量,但允许对象和数组的内部修改。两者在循环、函数内部及复杂项目中广泛应用,有助于实现不可变数据结构,提升代码质量。
187 5
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
333 0
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
291 2