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实现监控视频播放并打印日志
Jan 05 Javascript
Js可拖拽放大的层拖动特效实现方法
Feb 25 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
Aug 01 Javascript
AngularJs篇:使用AngularJs打造一个简易权限系统的实现代码
Dec 26 Javascript
jquery与ajax获取特殊字符实例详解
Jan 08 Javascript
Javascript中构造函数要注意的一些坑
Jan 23 Javascript
jQuery+CSS3实现点赞功能
Mar 13 Javascript
详解使用Vue Router导航钩子与Vuex来实现后退状态保存
Sep 11 Javascript
jQuery+ajax读取json数据并按照价格排序示例
Mar 28 jQuery
javascript中this的用法实践分析
Jul 29 Javascript
Vue实现手机扫描二维码预览页面效果
May 28 Javascript
vue在响应头response中获取自定义headers操作
Jul 24 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
真正面向对象编程:PHP5.01发布
2006/10/09 PHP
从一个不错的留言本弄的mysql数据库操作类
2007/09/02 PHP
php 301转向实现代码
2008/09/18 PHP
PHP中运用jQuery的Ajax跨域调用实现代码
2012/02/21 PHP
php使用str_replace实现输入框回车替换br的方法
2014/11/24 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
仿163填写邮件地址自动显示下拉(无优化)
2008/11/05 Javascript
JavaScript的eval JSON object问题
2009/11/15 Javascript
javascript 面向对象的JavaScript类
2010/05/04 Javascript
JSQL 基于客户端的成绩统计实现方法
2010/05/05 Javascript
Web 前端设计模式--Dom重构 提高显示性能
2010/10/22 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
2013/12/04 Javascript
JS+CSS实现滑动切换tab菜单效果
2015/08/25 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
2016/12/08 Javascript
Bootstrap整体框架之JavaScript插件架构
2016/12/15 Javascript
node-sass安装失败的原因与解决方法
2017/09/04 Javascript
cocos creator Touch事件应用(触控选择多个子节点的实例)
2017/09/10 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
Vue自定义指令写法与个人理解
2019/02/09 Javascript
vue组件内部引入外部js文件的方法
2020/01/18 Javascript
在Python的web框架中配置app的教程
2015/04/30 Python
Python针对给定列表中元素进行翻转操作的方法分析
2018/04/27 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
2019/04/04 Python
Python 给屏幕打印信息加上颜色的实现方法
2019/04/24 Python
python实现大量图片重命名
2020/03/23 Python
Python socket处理client连接过程解析
2020/03/18 Python
基于CentOS搭建Python Django环境过程解析
2020/08/24 Python
python安装cx_Oracle和wxPython的方法
2020/09/14 Python
Java语言程序设计测试题选择题部分
2014/04/03 面试题
《故都的秋》教学反思
2014/04/15 职场文书
爱岗敬业演讲稿
2014/05/05 职场文书
省委召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
群众路线个人剖析材料及整改措施
2014/11/04 职场文书
教师读书活动心得体会
2016/01/14 职场文书
感谢信的技巧及范例
2019/05/15 职场文书
MySQL去除重叠时间求时间差和的实现
2021/08/23 MySQL