前言

胖箭头函数(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

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

JavaScript ES6箭头函数指南的更多相关文章

  1. javascript es6 箭头函数

    1.箭头函数示例 let add = (a,b) => a + b         //没有语句块时,默认作为返回值 add(1,2); var multi = (a,b) => {ret ...

  2. ES6 — 箭头函数

    一 为什么要有箭头函数 我们在日常开发中,可能会需要写类似下面的代码 const Person = { 'name': 'little bear', 'age': 18, 'sayHello': fu ...

  3. 前端分享----JS异步编程+ES6箭头函数

    前端分享----JS异步编程+ES6箭头函数 ##概述Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只 ...

  4. ES6 箭头函数 this 指向

    ES6 箭头函数 this 指向 箭头函数有几个使用注意点: 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象. 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个 ...

  5. 02、Java的lambda表达式和JavaScript的箭头函数

    前言 在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系:本次试图通过这篇文章弄懂上面的两个"语法糖". 简介 ...

  6. this(ES6箭头函数里的this)

    一,了解前须知 1,箭头函数:出现的作用除了让函数的书写变得很简洁,可读性很好外:最大的优点是解决了this执行环境所造成的一些问题.比如:解决了匿名函数this指向的问题(匿名函数的执行环境具有全局 ...

  7. ES6 箭头函数及this

    ES6 箭头函数及this 1.箭头函数 <script type="text/javascript"> //以前定义函数 let fun=function () { ...

  8. es6箭头函数讲解

    es6箭头函数的用法 箭头函数是es6的一种函数的简写方法. 如下: var f = v = > v; //等同于 var f = function(v){ return v; } var su ...

  9. es6箭头函数 this 指向问题

    es5中 this 的指向 var factory = function(){ this.a = 'a'; this.b = 'b'; this.c = { a:'a+', b:function(){ ...

随机推荐

  1. extern函数声明(转)

    转自:chao_yu extern 函数声明 常常见extern放在函数的前面成为函数声明的一部分,那么,C语言的关键字extern在函数的声明中起什么作用? 答案与分析: 如果函数的声明中带有关键字 ...

  2. tmux终端工具

    本文原始地址:http://www.cnblogs.com/chinas/p/7094172.html,转载请注明出处,谢谢!!! 1.介绍 tmux(终端复用工具):一个很有趣的工具,类似GNU S ...

  3. 【多视图几何】TUM 课程 第6章 多视图重建

    课程的 YouTube 地址为:https://www.youtube.com/playlist?list=PLTBdjV_4f-EJn6udZ34tht9EVIW7lbeo4 .视频评论区可以找到课 ...

  4. 【navicat112_premium】navicat112_premium数据库连接工具安装过程

    此工具及其方便,可以连接mysql.oracle.sqlserver登数据库... 1.下载安装包Navicat Premium_11.2.7简体中文版.rar 下载地址:http://qiaoliq ...

  5. docker制作镜像步骤

    一.查看宿主机下是否有符合需求的docker镜像 操作命令如下: [root@server4 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZ ...

  6. MySQL数据记录大小写敏感问题【转】

    MySQL大小写敏感 字符串大小写敏感和Mysql的数据库的名字.表名字.字段名字.还有字段值有关. 1.和数据库名字.表名字.存储过程和触发器有关 为0时:表示区分大小写,使用CREATE TABL ...

  7. sed实例收集

    url:http://blog.csdn.net/hepeng597/article/details/7852468 一.元字符集    1)^锚定行的开始 如:/^sed/匹配所有以sed开头的行. ...

  8. Android图片异步加载

    原:http://www.cnblogs.com/angeldevil/archive/2012/09/16/2687174.html 相关:https://github.com/nostra13/A ...

  9. java基础44 IO流技术(输出字节流/缓冲输出字节流)和异常处理

    一.输出字节流 输出字节流的体系: -------| OutputStream:所有输出字节流的基类(抽象类) ----------| FileOutputStream:向文件输出数据的输出字节流(把 ...

  10. java基础33 Set集合下的HashSet集合和TreeSet集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...