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 相关文章推荐
prototype 1.5相关知识及他人笔记
Dec 16 Javascript
ExtJS4如何给同一个formpanel不同的url
May 02 Javascript
jquery中使用循环下拉菜单示例代码
Sep 24 Javascript
基于jquery实现等比缩放图片
Dec 03 Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
Jan 26 Javascript
JavaScript中获取时间的函数集
Aug 16 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
Jan 19 Javascript
AngularJS学习第一篇 AngularJS基础知识
Feb 13 Javascript
Vue.js展示AJAX数据简单示例讲解
Mar 29 Javascript
Node.JS更改Windows注册表Regedit的方法小结
Aug 18 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
Jan 29 Javascript
解决vue路由name同名,路由重复的问题
Aug 05 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面向对象精要总结
2014/11/07 PHP
网站防止被刷票的一些思路与方法
2015/01/08 PHP
PHP中返回引用类型的方法
2015/04/03 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
浅谈mysql_query()函数的返回值问题
2016/09/05 PHP
Fleaphp常见函数功能与用法示例
2016/11/15 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
利用PHPStorm如何开发Laravel应用详解
2017/08/30 PHP
js之WEB开发调试利器:Firebug 下载
2007/01/13 Javascript
JS获取scrollHeight问题想到的标准问题
2007/05/27 Javascript
JavaScript中清空数组的三种方法分享
2011/04/07 Javascript
Node.js中的模块机制学习笔记
2014/11/04 Javascript
angularjs中的单元测试实例
2014/12/06 Javascript
javascript常见数据验证插件大全
2015/08/03 Javascript
js+html制作简单日历的方法
2017/06/27 Javascript
JS实现字符串翻转的方法分析
2018/08/31 Javascript
利用原生JavaScript实现造日历轮子实例代码
2019/05/08 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
2019/05/21 Javascript
用python写asp详细讲解
2013/12/16 Python
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
python requests 使用快速入门
2017/08/31 Python
python下载库的步骤方法
2019/10/12 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
纯CSS3实现绘制各种图形实现代码详细整理
2012/12/26 HTML / CSS
西班牙购买隐形眼镜、眼镜和太阳镜网站:Lentiamo.es
2020/06/11 全球购物
医学类导师推荐信范文
2013/11/19 职场文书
行政文秘岗位职责范本
2014/02/10 职场文书
民主生活会对照检查材料(统计局)
2014/09/21 职场文书
2014年财务科工作总结
2014/11/11 职场文书
二年级上册数学教学计划
2015/01/20 职场文书
2015年初三班主任工作总结
2015/05/21 职场文书
小学音乐课教学反思
2016/02/18 职场文书
Nginx使用X-Accel-Redirect实现静态文件下载的统计、鉴权、防盗链、限速等
2021/04/04 Servers
css3实现背景图片半透明内容不透明的方法示例
2021/04/13 HTML / CSS
PostgreSQL基于pgrouting的路径规划处理方法
2022/04/18 PostgreSQL
使用scrapy实现增量式爬取方式
2022/06/21 Python