深入理解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 相关文章推荐
jquery加载页面的方法(页面加载完成就执行)
Jun 21 Javascript
JavaScript的事件绑定(方便不支持js的时候)
Oct 01 Javascript
文档对象模型DOM通俗讲解
Nov 01 Javascript
使用AOP改善javascript代码
May 01 Javascript
node.js回调函数之阻塞调用与非阻塞调用
Nov 13 Javascript
JavaScript必知必会(六) delete in instanceof
Jun 08 Javascript
vue.js路由跳转详解
Aug 28 Javascript
vue.js项目nginx部署教程
Apr 05 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
May 30 jQuery
Node.js系列之连接DB的方法(3)
Aug 30 Javascript
countup.js实现数字动态叠加效果
Oct 17 Javascript
详解Vue中的自定义指令
Dec 07 Vue.js
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(4) php 函数 补充2
2010/02/15 PHP
超级实用的7个PHP代码片段分享
2012/01/05 PHP
用来解析.htgroup文件的PHP类
2012/09/05 PHP
php中删除数组的第一个元素和最后一个元素的函数
2015/03/07 PHP
PHP用FTP类上传文件视频等的简单实现方法
2016/09/23 PHP
php微信公众平台示例代码分析(二)
2016/12/06 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
Array对象方法参考
2006/10/03 Javascript
fireworks菜单生成器mm_menu.js在 IE 7.0 显示问题的解决方法
2009/10/20 Javascript
JS左右无缝滚动(一般方法+面向对象方法)
2012/08/17 Javascript
基于jquery DOM写的类似微博发布的效果
2012/10/20 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
2013/10/29 Javascript
JS实现字体选色板实例代码
2013/11/20 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
2015/03/04 Javascript
在Node.js应用中读写Redis数据库的简单方法
2015/06/30 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
BootStrap Tooltip插件源码解析
2016/12/27 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
Node.js连接mongodb实例代码
2017/06/06 Javascript
Vue入门之animate过渡动画效果
2018/04/08 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
基于Nuxt.js项目的服务端性能优化与错误检测(容错处理)
2019/10/23 Javascript
解决node终端下运行js文件不支持ES6语法
2020/04/04 Javascript
jQuery冲突问题解决方法
2021/01/19 jQuery
[05:20]卡尔工作室_DOTA2新手教学_DOTA2超强新手功能
2013/04/22 DOTA
Python collections模块实例讲解
2014/04/07 Python
使用Python更换外网IP的方法
2018/07/09 Python
美津浓巴西官方网站:Mizuno巴西
2019/07/24 全球购物
SmartBuyGlasses比利时:购买品牌太阳镜和眼镜
2019/08/09 全球购物
判断单链表中是否存在环
2012/07/16 面试题
电气自动化专业职业规划范文
2014/02/16 职场文书
服务质量承诺书
2014/03/27 职场文书
小学生心理健康活动总结
2015/05/08 职场文书
Python利器openpyxl之操作excel表格
2021/04/17 Python
如何用python反转图片,视频
2021/04/24 Python