JavaScript箭头(arrow)函数详解


Posted in Javascript onJune 04, 2017

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

本文我们介绍箭头(arrow)函数的优点。

更简洁的语法

我们先来按常规语法定义函数:

function funcName(params) {
  return params + 2;
 }
funcName(2);
// 4

该函数使用箭头函数可以使用仅仅一行代码搞定!

var funcName = (params) => params + 2
funcName(2);
// 4

是不是很酷!虽然是一个极端简洁的例子,但是很好的表述了箭头函数在写代码时的优势。我们来深入了解箭头函数的语法:
(parameters) => { statements }

如果没有参数,那么可以进一步简化:
() => { statements }

如果只有一个参数,可以省略括号:
parameters => { statements }

如果返回值仅仅只有一个表达式(expression), 还可以省略大括号:
parameters => expression

// 等价于:
function (parameters){
 return expression;
}

现在你已经学会了箭头函数的语法,我们来实战一下。打开Chrome浏览器开发者控制台,输入:
var double = num => num * 2

我们将变量 double 绑定到一个箭头函数,该函数有一个参数 num , 返回 num * 2 。 调用该函数:

double(2);
// 4

double(3);
// 6

没有局部 this 的绑定

和一般的函数不同,箭头函数不会绑定 this 。 或则说箭头函数不会改变 this 本来的绑定。

我们用一个例子来说明:

function Counter() {
 this.num = 0;
}
var a = new Counter();

因为使用了关键字 new 构造,Count()函数中的 this 绑定到一个新的对象,并且赋值给 a 。通过 console.log 打印

a.num ,会输出0。 
console.log(a.num);
// 0

如果我们想每过一秒将 a.num 的值加1,该如何实现呢?可以使用 setInterval() 函数。

function Counter() {
 this.num = 0;
 this.timer = setInterval(function add() {
  this.num++;
  console.log(this.num);
 }, 1000);
}

我们来看一下输出结果:

var b = new Counter();
// NaN
// NaN
// NaN
// ...

你会发现,每隔一秒都会有一个 NaN 打印出来,而不是累加的数字。到底哪里错了呢?

首先使用如下语句停止 setInterval 函数的连续执行:
clearInterval(b.timer);

我们来尝试理解为什么出错:根据上一篇博客讲解的规则,首先函数 setInterval 没有被某个声明的对象调用,也没有使用 new 关键字,再之没有使用 bind , call 和 apply 。 setInterval 只是一个普通的函数。实际上 setInterval 里面的 this 绑定到全局对象的。我们可以通过将 this 打印出来验证这一点:

function Counter() {
 this.num = 0;
this.timer = setInterval(function add() {
  console.log(this);
 }, 1000);
}
var b = new Counter();

你会发现,整个 window 对象被打印出来。 使用如下命令停止打印:
clearInterval(b.timer);

回到之前的函数,之所以打印 NaN ,是因为 this.num 绑定到 window 对象的 num ,而 window.num 未定义。

那么,我们如何解决这个问题呢?使用箭头函数!使用箭头函数就不会导致 this 被绑定到全局对象。

function Counter() {
 this.num = 0;
 this.timer = setInterval(() => {
  this.num++;
  console.log(this.num);
 }, 1000);
}
var b = new Counter();
// 1
// 2
// 3
// ...

通过 Counter 构造函数绑定的 this 将会被保留。在 setInterval 函数中, this 依然指向我们新创建的 b 对象。

为了验证刚刚的说法,我们可以将 Counter 函数中的 this 绑定到 that , 然后在 setInterval 中判断 this 和 that 是否相同。

function Counter() {
 var that = this;
 this.timer = setInterval(() => {
  console.log(this === that);
 }, 1000);
}
var b = new Counter();
// true
// true
// ...

正如我们期望的,打印值每次都是 true 。最后,结束刷屏的打印:
clearInterval(b.timer);

总结

1.箭头函数写代码拥有更加简洁的语法;

2. 不会绑定 this 。

原文: JavaScript: Arrow Functions for Beginners

译者: Fundebug

译者按:箭头函数看上去只是语法的变动,其实也影响了 this 的作用域。

Javascript 相关文章推荐
JavaScript 学习笔记一些小技巧
Mar 28 Javascript
javascript工厂方式定义对象
Dec 26 Javascript
jQuery中[attribute]选择器用法实例
Dec 31 Javascript
javascript中加var和不加var的区别 你真的懂吗
Jan 06 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
Jun 11 Javascript
详解Vue微信公众号开发踩坑全记录
Aug 21 Javascript
jQuery实现的网站banner图片无缝轮播效果完整实例
Jan 28 jQuery
JS module的导出和导入的实现代码
Feb 25 Javascript
用Node写一条配置环境的指令
Nov 14 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
Mar 26 Javascript
小程序实现点击tab切换左右滑动
Nov 16 Javascript
vue实现列表拖拽排序的示例代码
Apr 08 Vue.js
Angular 4依赖注入学习教程之简介(一)
Jun 04 #Javascript
angularJs中datatable实现代码
Jun 03 #Javascript
angularJS利用ng-repeat遍历二维数组的实例代码
Jun 03 #Javascript
详解JavaScript调用栈、尾递归和手动优化
Jun 03 #Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
Jun 03 #Javascript
利用vueJs实现图片轮播实例代码
Jun 03 #Javascript
angular中使用Socket.io实例代码
Jun 03 #Javascript
You might like
php调用google接口生成二维码示例
2014/04/28 PHP
thinkphp的URL路由规则与配置实例
2014/11/26 PHP
效率高的Javscript字符串替换函数的benchmark
2008/08/02 Javascript
js报$ is not a function 的问题的解决方法
2014/01/20 Javascript
Javascript基础教程之比较操作符
2015/01/18 Javascript
JavaScript中的对象与JSON
2015/07/03 Javascript
前端自动化开发之Node.js的环境搭建教程
2017/04/01 Javascript
javascript 初学教程及五子棋小程序的简单实现
2017/07/04 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
2017/12/05 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
2018/11/22 Javascript
mock.js实现模拟生成假数据功能示例
2019/01/15 Javascript
vue-router实现编程式导航的代码实例
2019/01/19 Javascript
解决layer弹出层msg的文字不显示的问题
2019/09/11 Javascript
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
[01:10:02]IG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
利用Fn.py库在Python中进行函数式编程
2015/04/22 Python
详细讲解用Python发送SMTP邮件的教程
2015/04/29 Python
Python中的time模块与datetime模块用法总结
2016/06/30 Python
Python实现文件信息进行合并实例代码
2018/01/17 Python
对numpy下的轴交换transpose和swapaxes的示例解读
2019/06/26 Python
使用 Django Highcharts 实现数据可视化过程解析
2019/07/31 Python
Pytorch实现LSTM和GRU示例
2020/01/14 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
Flask模板引擎Jinja2使用实例
2020/04/23 Python
CSS3中Color的一些特性介绍
2012/05/27 HTML / CSS
加拿大时尚少女服装品牌:Garage
2016/10/10 全球购物
Java面试题:请说出如下代码的输出结果
2013/04/22 面试题
给领导的致歉信范文
2014/01/13 职场文书
带薪年假请假条
2014/02/04 职场文书
高级编程求职信模板
2014/02/16 职场文书
四风批评与自我批评范文
2014/10/14 职场文书
2015年中个人总结范文
2015/03/10 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL