Javascript对象中关于setTimeout和setInterval的this介绍


Posted in Javascript onJuly 21, 2012

在Javascript里,setTimeout和setInterval接收第一个参数是一个字符串或者一个函数,当在一个对象里面用setTimeout延时调用该对象的方法时

function obj() { 
this.fn = function() { 
alert("ok"); 
console.log(this); 
setTimeout(this.fn, 1000);//直接使用this引用当前对象 
} 
} 
var o = new obj(); 
o.fn();

然后我们发现上面的代码不是想要的结果,原因是setTimeout里面的this是指向window,所以要调用的函数变成 window.fn 为undefined,于是悲剧了。所以问题的关键在于得到当前对象的引用,于是有以下三种方法
// 方法一: function obj() { 
this.fn = function() { 
alert("ok"); 
console.log(this); 
setTimeout(this.fn.bind(this), 1000);//通过Function.prototype.bind 绑定当前对象 
} 
} 
var o = new obj(); 
o.fn();

这样可以得到正确的结果,可惜Function.prototype.bind方法是ES5新增的标准,测试了IE系列发现IE6-8都不支持,只有IE9+可以使用。要想兼容就得简单的模拟下bind,看下面的代码
// 方法二: 
function obj() { 
this.fn = function() { 
alert("ok"); 
setTimeout((function(a,b){ 
return function(){ 
b.call(a); 
} 
})(this,this.fn), 1000);//模拟Function.prototype.bind 
} 
} 
var o = new obj(); 
o.fn();

首先通过一个自执行匿名函数传当前对象和对象方法进去,也就是里面的参数a和b,再返回一个闭包,通过call方法使this指向正确。下面是比较简洁的方法
// 方法三: 
function obj() { 
this.fn = function() { 
var that = this;//保存当前对象this 
alert("ok"); 
setTimeout(function(){ 
that.fn(); 
}, 1000);//通过闭包得到当前作用域,好访问保存好的对象that 
} 
} 
var o = new obj(); 
o.fn();

上面第三个方法的两个关键点是 保存当前对象this为别名that 和 通过闭包得到当前作用域,以访问保存好的对象that;当对象方法里面多层嵌套函数或者setTimeout,setInterval等方法丢失this(也就是this不指向当前对象而是window),所以在this指向正确的作用域保存var that = this就变得很实用了
Javascript 相关文章推荐
javascript 子窗体父窗体相互传值方法
May 31 Javascript
javascript下数值型比较难点说明
Jun 07 Javascript
javascript设计模式 接口介绍
Jul 24 Javascript
ExtJS自定义主题(theme)样式详解
Nov 18 Javascript
Bootstrap每天必学之表单
Nov 23 Javascript
jQuery 选择同时包含两个class的元素的实现方法
Jun 01 Javascript
三种带箭头提示框总结实例
Jun 14 Javascript
webpack4 css打包压缩问题的解决
May 18 Javascript
Vue的watch和computed方法的使用及区别介绍
Sep 06 Javascript
Angular8 实现table表格表头固定效果
Jan 03 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
Apr 14 Javascript
Vue实现可移动水平时间轴
Jun 29 Javascript
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
Jul 21 #Javascript
Javascript中找到子元素在父元素内相对位置的代码
Jul 21 #Javascript
分享XmlHttpRequest调用Webservice的一点心得
Jul 20 #Javascript
基于jquery的可多选的下拉列表框
Jul 20 #Javascript
基于jquery的DIV随滚动条滚动而滚动的代码
Jul 20 #Javascript
最佳6款用于移动网站开发的jQuery 图片滑块插件小结
Jul 20 #Javascript
基于jquery的图片轮播 tab切换组件
Jul 19 #Javascript
You might like
全国FM电台频率大全 - 23 四川省
2020/03/11 无线电
用PHP和MySQL保存和输出图片
2006/10/09 PHP
微信随机生成红包金额算法php版
2016/07/21 PHP
示例详解Laravel重置密码代码重构
2016/08/10 PHP
Yii2实现自定义独立验证器的方法
2017/05/05 PHP
Thinkphp5结合layer弹窗定制操作结果页面
2017/07/07 PHP
PHP实现的分解质因数操作示例
2018/08/01 PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
2019/06/22 PHP
js判断屏幕分辨率的代码
2013/07/16 Javascript
node.js超时timeout详解
2014/11/26 Javascript
JavaScript实现标题栏文字轮播效果代码
2015/10/24 Javascript
鼠标悬停小图标显示大图标
2016/01/22 Javascript
jqPlot jQuery绘图插件的使用
2016/06/18 Javascript
网络传输协议(http协议)
2016/11/18 Javascript
Vue.js结合bootstrap实现分页控件
2017/03/10 Javascript
详解JavaScript中return的用法
2017/05/08 Javascript
vue组件生命周期详解
2017/11/07 Javascript
jQuery Validate插件ajax方式验证输入值的实例
2017/12/21 jQuery
JS高级技巧(简洁版)
2018/07/29 Javascript
vue+egg+jwt实现登录验证的示例代码
2019/05/18 Javascript
html2canvas属性和使用方法以及如何使用html2canvas将HTML内容写入Canvas生成图片
2020/01/12 Javascript
Vue实现剪切板图片压缩功能
2020/02/04 Javascript
详解Vue 单文件组件的三种写法
2020/02/19 Javascript
[02:23]DOTA2英雄基础教程 幻影长矛手
2013/12/09 DOTA
[06:37]2014DOTA2国际邀请赛 昔日王者渴望重回巅峰
2014/07/12 DOTA
python shell根据ip获取主机名代码示例
2017/11/25 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
2019/06/14 Python
python使用minimax算法实现五子棋
2019/07/29 Python
使用Matplotlib绘制不同颜色的带箭头的线实例
2020/04/17 Python
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
ORACLE十问
2015/04/20 面试题
支教自我鉴定
2014/01/18 职场文书
总经理秘书岗位职责
2014/03/17 职场文书
纪念九一八事变83周年国旗下讲话稿
2014/09/15 职场文书
全陪导游词
2015/02/04 职场文书
停电调休通知
2015/04/16 职场文书