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 相关文章推荐
9个JavaScript评级/投票插件
Jan 18 Javascript
JS嵌套函数调用上下文的问题解决
Mar 26 Javascript
jquery实现选中单选按钮下拉伸缩效果
Aug 06 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
Dec 13 Javascript
微信小程序 数组(增,删,改,查)等操作实例详解
Jan 05 Javascript
微信小程序实现登录页云层漂浮的动画效果
May 05 Javascript
微信小程序swiper组件用法实例分析【附源码下载】
Dec 07 Javascript
Vue-cli Eslint在vscode里代码自动格式化的方法
Feb 23 Javascript
Vue中$refs的用法详解
Jun 24 Javascript
如何解决webpack-dev-server代理常切换问题
Jan 09 Javascript
JavaScript运行机制实例分析
Apr 11 Javascript
vue3.0 加载json的方法(非ajax)
Oct 26 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 adodb分页实现代码
2009/03/19 PHP
PHP 金额数字转换成英文
2010/05/06 PHP
PHP header()函数使用详细(301、404等错误设置)
2013/04/17 PHP
php判断输入是否是纯数字,英文,汉字的方法
2015/03/05 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
2016/06/30 PHP
php使用glob函数遍历文件和目录详解
2016/09/23 PHP
轻松掌握php设计模式之访问者模式
2016/09/23 PHP
PHP常用日期加减计算方法实例小结
2018/07/31 PHP
Mootools 1.2教程 事件处理
2009/09/15 Javascript
JQuery困惑—包装集 DOM节点
2009/10/16 Javascript
通过Jscript中@cc_on 语句识别IE浏览器及版本的代码
2011/05/07 Javascript
博客侧边栏模块跟随滚动条滑动固定效果的实现方法(js+jquery等)
2013/03/24 Javascript
IE 下Enter提交表单存在重复提交问题的解决方法
2014/05/04 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
2014/11/28 Javascript
jquery中filter方法用法实例分析
2015/02/06 Javascript
js前端实现多图图片上传预览的两个方法(推荐)
2016/11/18 Javascript
原生JS轮播图插件
2017/02/09 Javascript
vue select组件的使用与禁用实现代码
2018/04/10 Javascript
jQuery基于随机数解决中午吃什么去哪吃问题示例
2018/12/29 jQuery
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
在vue中使用Base64转码的案例
2020/08/07 Javascript
[28:05]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第一场 10月30日
2020/10/31 DOTA
python执行CMD指令,并获取返回的方法
2018/12/19 Python
使用Python做定时任务及时了解互联网动态
2019/05/15 Python
Python 列表推导式需要注意的地方
2020/10/23 Python
解决使用Pandas 读取超过65536行的Excel文件问题
2020/11/10 Python
CSS3毛玻璃效果(blur)有白边问题的解决方法
2016/11/15 HTML / CSS
Johnston & Murphy官网: 约翰斯顿·墨菲牛津总统鞋
2018/01/09 全球购物
Java中实现多态的机制是什么?
2014/12/07 面试题
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?
2016/08/18 面试题
JAVA招聘远程笔试题
2015/07/23 面试题
建筑工程造价专业自荐信
2014/07/08 职场文书
庆祝国庆节演讲稿2014
2014/09/19 职场文书
2014年师德师风工作总结
2014/11/25 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
python3读取文件指定行的三种方法
2021/05/24 Python