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 相关文章推荐
js获取变量
Aug 24 Javascript
最短的IE判断代码
Mar 13 Javascript
六款帮助你实现惊艳视差滚动效果的jQuery插件
Sep 14 Javascript
js+canvas简单绘制圆圈的方法
Jan 28 Javascript
JS区分浏览器页面是刷新还是关闭
Apr 17 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
Dec 20 Javascript
原生js实现轮播图的示例代码
Feb 20 Javascript
JavaScript私有变量实例详解
Jan 24 Javascript
vue实现codemirror代码编辑器中的SQL代码格式化功能
Aug 27 Javascript
vue使用i18n实现国际化的方法详解
Sep 05 Javascript
浅谈VUE中演示v-for为什么要加key
Jan 16 Javascript
JavaScript位置参数实现原理及过程解析
Sep 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加MYSQL服务器
2006/10/09 PHP
php获得用户ip地址的比较不错的方法
2014/02/08 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
2014/08/18 PHP
PHP读取配置文件类实例(可读取ini,yaml,xml等)
2015/07/28 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
使用javascipt---实现二分查找法
2013/04/10 Javascript
javascript中的startWith和endWith的几种实现方法
2013/05/07 Javascript
浅析Js(Jquery)中,字符串与JSON格式互相转换的示例(直接运行实例)
2013/07/09 Javascript
js控制table合并具体实现
2014/02/20 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
javascript实现限制上传文件大小
2015/02/06 Javascript
JavaScript中的acos()方法使用详解
2015/06/14 Javascript
php结合imgareaselect实现图片裁剪
2015/07/05 Javascript
浅谈jQuery为哪般去掉了浏览器检测
2016/08/29 Javascript
微信小程序 循环及嵌套循环的使用总结
2017/09/26 Javascript
详解vue 计算属性与方法跟侦听器区别(面试考点)
2018/04/23 Javascript
解决layui中的form表单与button的点击事件冲突问题
2018/08/15 Javascript
浅析JS中什么是自定义react数据验证组件
2018/10/19 Javascript
vue父子组件通信的高级用法示例
2019/08/29 Javascript
NodeJS http模块用法示例【创建web服务器/客户端】
2019/11/05 NodeJs
python读取浮点数和读取文本文件示例
2014/05/06 Python
python实现的登录和操作开心网脚本分享
2014/07/09 Python
Python3结合Dlib实现人脸识别和剪切
2018/01/24 Python
python socket 聊天室实例代码详解
2019/11/14 Python
python保留小数位的三种实现方法
2020/01/07 Python
Python *args和**kwargs用法实例解析
2020/03/02 Python
Django在Model保存前记录日志实例
2020/05/14 Python
python接入支付宝的实例操作
2020/07/20 Python
Python 如何反方向迭代一个序列
2020/07/28 Python
一款CSS3实现多功能下拉菜单(带分享按)的教程
2014/11/05 HTML / CSS
Intimissimi德国网上商店:意大利知名内衣品牌
2018/04/03 全球购物
工商管理专业职业生涯规划
2014/01/01 职场文书
学习十八届三中全会精神实施方案
2014/02/17 职场文书
村干部承诺书
2014/03/28 职场文书
2014年司法局工作总结
2014/12/11 职场文书
运动会开幕词
2015/01/28 职场文书