深入理解Javascript箭头函数中的this


Posted in Javascript onFebruary 13, 2017

首先我们先看一段代码,这是一个实现倒数功能的类「Countdown」及其实例化的过程:

function Countdown(seconds) {
 this._seconds = seconds;
}
Countdown.prototype._step = function() {
 console.log(this._seconds);
 if (this._seconds > 0) {
  this._seconds -= 1;
 } else {
  clearInterval(this._timer);
 }
};
Countdown.prototype.start = function() {
 this._step();
 this._timer = setInterval(function() {
  this._step();
 }, 1000);
};

new Countdown(10).start();

运行这段代码时,将会出现异常「this._step is not a function」。

这是Javascript中颇受诟病的「this错乱」问题:setInterval重复执行的函数中的this已经跟外部的this不一致了。

要解决这个问题,有三个方法。

闭包

新增一个变量指向期望的this,然后将该变量放到闭包中:

Countdown.prototype.start = function() {
 var self = this;
 this._step();
 this._timer = setInterval(function() {
  self._step();
 }, 1000);
};

bind函数

ES5给函数类型新增的「bind」方法可以改变函数(实际上是返回了一个新的函数)的「this」:

Countdown.prototype.start = function() {
  this._step();
  this._timer = setInterval(function() {
    this._step();
  }.bind(this), 1000);
};

箭头函数

这正是本文要重点介绍的解决方案。箭头函数是ES6中新增的语言特性,表面上看,它只是使匿名函数的编码更加简短,但实际上它还隐藏了一个非常重要的细节——箭头函数会捕获其所在上下文的this作为自己的this。也就是说,箭头函数内部与其外部的this是保持一致的。

所以,解决方案如下:

Countdown.prototype.start = function() {
  this._step();
  this._timer = setInterval(() => {
    this._step();
  }, 1000);
};

这无疑使this的处理更加方便了。然而,对各位Javascript Coder而言,判断this指向时的情况可就又多了一种了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
用JavaScript编写COM组件的步骤
Mar 17 Javascript
JS中处理与当前时间间隔的函数代码
May 23 Javascript
AngularJS包括详解及示例代码
Aug 17 Javascript
详解通过JSON数据使用VUE.JS
May 26 Javascript
js 发布订阅模式的实例讲解
Sep 10 Javascript
node.js环境搭建图文详解
Sep 19 Javascript
BootStrap中的模态框(modal,弹出层)功能示例代码
Nov 02 Javascript
基于Koa2写个脚手架模拟接口服务的方法
Nov 27 Javascript
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
Dec 09 Javascript
微信小程序录音实现功能并上传(使用node解析接收)
Feb 26 Javascript
vue props 一次传多个值实例
Jul 22 Javascript
js制作提示框插件
Dec 24 Javascript
ES6学习之变量的解构赋值
Feb 12 #Javascript
AngularJS实现路由实例
Feb 12 #Javascript
jQuery文字轮播特效
Feb 12 #Javascript
jQuery Mobile漏洞会有跨站脚本攻击风险
Feb 12 #Javascript
jQuery、zepto、js常用小技巧
Feb 12 #Javascript
JS中如何实现Laravel的route函数详解
Feb 12 #Javascript
js输入框使用正则表达式校验输入内容的实例
Feb 12 #Javascript
You might like
PHP 中执行排序与 MySQL 中排序
2009/04/21 PHP
Yii2增删改查之查询 where参数详细介绍
2016/08/08 PHP
Laravel框架中集成MongoDB和使用详解
2019/10/17 PHP
大家未必知道的Js技巧收藏
2008/04/07 Javascript
jQuery 第二课 操作包装集元素代码
2010/03/14 Javascript
JavaScript创建对象的写法
2013/08/29 Javascript
js动态往表格的td中添加图片并注册事件
2014/06/12 Javascript
JS+DIV实现鼠标划过切换层效果的方法
2015/05/25 Javascript
分享经典的JavaScript开发技巧
2015/11/21 Javascript
vue.js表格分页示例
2016/10/18 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
vue源码解析之事件机制原理
2018/04/21 Javascript
详解关于Vue单元测试的几个坑
2020/04/26 Javascript
vue实现列表滚动的过渡动画
2020/06/29 Javascript
Python ORM框架SQLAlchemy学习笔记之关系映射实例
2014/06/10 Python
Python科学画图代码分享
2017/11/29 Python
Python实现GUI学生信息管理系统
2020/04/05 Python
Python实现加载及解析properties配置文件的方法
2018/03/29 Python
利用python循环创建多个文件的方法
2018/10/25 Python
Python从list类型、range()序列简单认识类(class)【可迭代】
2019/05/31 Python
pyQt5实时刷新界面的示例
2019/06/25 Python
django Admin文档生成器使用详解
2019/07/22 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
2020/03/12 Python
Python实现验证码识别
2020/06/15 Python
python实现AHP算法的方法实例(层次分析法)
2020/09/09 Python
Selenium 安装和简单使用的实现
2020/12/04 Python
Canvas实现放大镜效果完整案例分析(附代码)
2020/11/26 HTML / CSS
彪马荷兰官网:PUMA荷兰
2019/05/08 全球购物
2014年应届大学生毕业自我鉴定
2014/01/31 职场文书
求职信名称怎么写
2014/05/26 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
2014幼儿园班主任工作总结
2014/12/04 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
golang 如何用反射reflect操作结构体
2021/04/28 Golang
分享几个实用的CSS代码块
2022/06/10 HTML / CSS
JS前端可扩展的低代码UI框架Sunmao使用详解
2022/07/23 Javascript