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 判断函数类型完美解决方案
Sep 02 Javascript
JQuery插件开发示例代码
Nov 06 Javascript
jquery退出each循环的写法
Feb 26 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
May 28 Javascript
innerHTML中标签可以换行的方法汇总
Aug 14 Javascript
Angular的MVC和作用域
Dec 26 Javascript
javascript回调函数的概念理解与用法分析
May 27 Javascript
Vue.js 点击按钮显示/隐藏内容的实例代码
Feb 08 Javascript
如何在js代码中消灭for循环实例详解
Jul 29 Javascript
js prototype深入理解及应用实例分析
Nov 25 Javascript
vue导入.md文件的步骤(markdown转HTML)
Dec 31 Vue.js
JS中箭头函数与this的写法和理解
Jan 14 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
PHP实现加密的几种方式介绍
2015/02/22 PHP
PHP+JS实现的商品秒杀倒计时用法示例
2016/11/15 PHP
PHP 获取指定地区的天气实例代码
2017/02/08 PHP
PHP使用imagick扩展实现合并图像的方法
2017/04/25 PHP
javascript getElementsByName()的用法说明
2009/07/31 Javascript
javascript 遍历验证所有文本框的值
2009/08/27 Javascript
jQuery 使用手册(四)
2009/09/23 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
nodejs初步体验篇
2015/11/23 NodeJs
解决bootstrap导航栏navbar在IE8上存在缺陷的方法
2016/07/01 Javascript
AngularJS指令与指令之间的交互功能示例
2016/12/14 Javascript
Angular.JS内置服务$http对数据库的增删改使用教程
2017/05/07 Javascript
JavaScript登录验证基础教程
2017/11/01 Javascript
最实用的JS数组函数整理
2017/12/05 Javascript
select获取下拉框的值 下拉框默认选中方法
2018/02/28 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
[07:38]2014DOTA2国际邀请赛 Newbee顺利挺进胜者组赛后专访
2014/07/15 DOTA
PHP webshell检查工具 python实现代码
2009/09/15 Python
Python while 循环使用的简单实例
2016/06/08 Python
详解python Todo清单实战
2018/11/01 Python
Python Image模块基本图像处理操作小结
2019/04/13 Python
Python 序列化和反序列化库 MarshMallow 的用法实例代码
2020/02/25 Python
Python web如何在IIS发布应用过程解析
2020/05/27 Python
杰夫·班克斯男士服装网上商店:Jeff Banks
2019/10/24 全球购物
一套Delphi的笔试题一
2016/02/14 面试题
工作人员思想汇报
2014/01/09 职场文书
党员自我批评与反省材料
2014/02/10 职场文书
大学共青团员个人自我评价
2014/04/16 职场文书
优秀应届毕业生自荐书
2014/06/29 职场文书
施工安全责任书范本
2014/07/24 职场文书
骨干教师事迹材料
2014/12/17 职场文书
二十年同学聚会致辞
2015/07/28 职场文书
2016年9月份红领巾广播稿
2015/12/21 职场文书
中秋节英文祝福语句(14句)
2019/09/11 职场文书
pytorch中的numel函数用法说明
2021/05/13 Python