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 相关文章推荐
取得传值的函数
Oct 27 Javascript
js 实现无干扰阴影效果 简单好用(附文件下载)
Dec 27 Javascript
JavaScript 页面坐标相关知识整理
Jan 09 Javascript
JQUERY 设置SELECT选中项代码
Feb 07 Javascript
javascript框架设计读书笔记之字符串的扩展和修复
Dec 02 Javascript
jQuery子属性过滤选择器用法分析
Feb 10 Javascript
JavaScript箭头函数_动力节点Java学院整理
Jun 28 Javascript
Vue实现typeahead组件功能(非常靠谱)
Aug 26 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
Oct 12 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
Jan 02 jQuery
通过jquery的ajax请求本地的json文件方法
Aug 08 jQuery
微信小程序chooseImage的用法(从本地相册选择图片或使用相机拍照)
Aug 22 Javascript
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
曾在DC漫画界反派角色扮演的演员,谁才是你心目中的小丑之王?
2020/04/09 欧美动漫
PHP循环结构实例讲解
2014/02/10 PHP
PHP简单实现文本计数器的方法
2016/04/28 PHP
laravel接管Dingo-api和默认的错误处理方式
2019/10/25 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
nullJavascript中创建对象的五种方法实例
2013/05/07 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
js结合正则实现国内手机号段校验
2015/06/19 Javascript
Bootstrap表单布局样式源代码
2016/07/04 Javascript
JS函数修改html的元素内容,及修改属性内容的方法
2016/10/28 Javascript
用Angular实时获取本地Localstorage数据,实现一个模拟后台数据登入的效果
2016/11/09 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
JavaScript异步上传图片文件的实例代码
2017/07/04 Javascript
使用JS组件实现带ToolTip验证框的实例代码
2017/08/23 Javascript
Three.js中网格对象MESH的属性与方法详解
2017/09/27 Javascript
npm的lock机制解析
2019/06/20 Javascript
JavaScript函数Call、Apply原理实例解析
2020/02/17 Javascript
NodeJS多种创建WebSocket监听的方式(三种)
2020/06/04 NodeJs
Element-ui el-tree新增和删除节点后如何刷新tree的实例
2020/08/31 Javascript
Python中__call__用法实例
2014/08/29 Python
python中MySQLdb模块用法实例
2014/11/10 Python
Python出现segfault错误解决方法
2016/04/16 Python
使用python判断你是青少年还是老年人
2018/11/29 Python
python 实现turtle画图并导出图片格式的文件
2019/12/07 Python
详解Django3中直接添加Websockets方式
2020/02/12 Python
详解django使用include无法跳转的解决方法
2020/03/19 Python
详解CSS3中nth-child与nth-of-type的区别
2017/01/05 HTML / CSS
Zooplus葡萄牙:欧洲领先的网上宠物商店
2018/07/01 全球购物
几个人围成一圈的问题
2013/09/26 面试题
超市实习总结自我鉴定
2013/09/19 职场文书
小学英语教学反思案例
2014/02/04 职场文书
2014年科室工作总结范文
2014/12/19 职场文书
违反纪律检讨书范文
2015/05/07 职场文书
学前班教学反思
2016/02/24 职场文书
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android
python中对列表的删除和添加方法详解
2022/02/24 Python