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 相关文章推荐
jQuery选中select控件 无法设置selected的解决方法
Sep 01 Javascript
JavaScript常用全局属性与方法记录积累
Jul 03 Javascript
jQuery简单图表peity.js使用示例
May 02 Javascript
javascript使用正则表达式实现去掉空格之后的字符
Feb 15 Javascript
js模仿php中strtotime()与date()函数实现方法
Aug 11 Javascript
谈谈对offsetleft兼容性的理解
Nov 11 Javascript
AngularJS对动态增加的DOM实现ng-keyup事件示例
Mar 12 Javascript
微信小程序如何使用canvas二维码保存至手机相册
Jul 15 Javascript
layui 弹出删除确认界面的实例
Sep 06 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
Feb 05 Javascript
详解JavaScript作用域 闭包
Jul 29 Javascript
解决vue项目运行npm run serve报错的问题
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
理解PHP5中static和const关键字的区别
2007/03/19 PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
2014/06/12 PHP
php调用shell的方法
2014/11/05 PHP
基于PHP给大家讲解防刷票的一些技巧
2015/11/18 PHP
php批量修改表结构实例
2017/05/24 PHP
Mootools 1.2教程 同时进行多个形变动画
2009/09/15 Javascript
JS定时器实现数值从0到10来回变化
2016/12/09 Javascript
10道典型的JavaScript面试题
2017/03/22 Javascript
详解javascript appendChild()的完整功能
2018/08/18 Javascript
vue.js实现只能输入数字的输入框
2019/10/19 Javascript
用python分割TXT文件成4K的TXT文件
2009/05/23 Python
python使用webbrowser浏览指定url的方法
2015/04/04 Python
python面向对象入门教程之从代码复用开始(一)
2018/12/11 Python
python3+PyQt5 使用三种不同的简便项窗口部件显示数据的方法
2019/06/17 Python
在Pytorch中使用样本权重(sample_weight)的正确方法
2019/08/17 Python
python进程的状态、创建及使用方法详解
2019/12/06 Python
Win10里python3创建虚拟环境的步骤
2020/01/31 Python
PyCharm GUI界面开发和exe文件生成的实现
2020/03/04 Python
基于python实现删除指定文件类型
2020/07/21 Python
印度和世界各地的精美产品:Ikka Dukka
2018/02/12 全球购物
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
第二层交换机和路由器的区别?第三层交换机和路由器的区别?
2013/05/23 面试题
Java中采用什么结构来捕获、处理异常?各子句的顺序、功能如何
2013/10/07 面试题
啤酒销售实习自我鉴定
2013/09/24 职场文书
医院后勤自我鉴定
2013/10/13 职场文书
质检部岗位职责
2013/11/11 职场文书
业务代表的岗位职责
2013/11/16 职场文书
社区工作者感言
2014/03/02 职场文书
2014大学生职业生涯规划书最新范文
2014/09/13 职场文书
教师党员个人整改措施材料
2014/09/16 职场文书
2015年综治宣传月活动总结
2015/03/25 职场文书
开天辟地观后感
2015/06/09 职场文书
2015年暑假工作总结
2015/07/13 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书
mysql数据库入门第一步之创建表
2021/05/14 MySQL
Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题
2022/02/12 Redis