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 相关文章推荐
javascritp实现input输入框相关限制用法
Jun 29 Javascript
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
jQuery.event兼容各浏览器的event详细解析
Dec 18 Javascript
Jquery操作js数组及对象示例代码
May 11 Javascript
使用原生js实现页面蒙灰(mask)效果示例代码
Jun 20 Javascript
JQuery表格拖动调整列宽效果(自己动手写的)
Sep 01 Javascript
跟我学习javascript的var预解析与函数声明提升
Nov 16 Javascript
JS实现JSON.stringify的实例代码讲解
Feb 07 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
Feb 08 Javascript
vue.js的手脚架vue-cli项目搭建的步骤
Aug 30 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
Nov 20 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
Dec 03 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
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
destoon利用Rewrite规则设置网站安全
2014/06/21 PHP
php+ajax简单实现全选删除的方法
2016/12/06 PHP
关于PHP5.6+版本“No input file specified”问题的解决
2019/12/11 PHP
如何运行/调试你的PHP代码
2020/10/23 PHP
JQuery中html()方法使用不当带来的陷阱
2011/04/07 Javascript
jQuery点击弹出下拉菜单的小例子
2013/08/01 Javascript
给html超链接设置事件不使用href来完成跳
2014/04/20 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
在JavaScript中处理时间之setMinutes()方法的使用
2015/06/11 Javascript
jQuery中 delegate使用的问题
2015/07/03 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
2015/12/10 Javascript
javascript实现保留两位小数的多种方法
2015/12/18 Javascript
JQuery动态添加Select的Option元素实现方法
2016/08/29 Javascript
微信小程序开发探究
2016/12/27 Javascript
详解微信小程序开发之——wx.showToast(OBJECT)的使用
2017/01/18 Javascript
Bootstrap Table从零开始
2017/06/30 Javascript
js 监控iframe URL的变化实例代码
2017/07/12 Javascript
Javascript三种字符串连接方式及性能比较
2019/05/28 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
Window10下python3.7 安装与卸载教程图解
2019/09/30 Python
简单了解python调用其他脚本方法实例
2020/03/26 Python
python 通过 pybind11 使用Eigen加速代码的步骤
2020/12/07 Python
python通过cython加密代码
2020/12/11 Python
matplotlib实现数据实时刷新的示例代码
2021/01/05 Python
css3 实现滚动条美化效果的实例代码
2021/01/06 HTML / CSS
html5 input元素新特性_动力节点Java学院整理
2017/07/06 HTML / CSS
英国花园家具中心:Garden Furniture Centre
2017/08/24 全球购物
澳大利亚领先的内衣店:Bendon Lingerie澳大利亚
2020/05/15 全球购物
毕业生的求职信范文分享
2013/12/04 职场文书
第一批党的群众路线教育实践活动工作总结
2014/03/03 职场文书
大学军训自我鉴定大全
2014/09/18 职场文书
财产分割协议书
2016/03/22 职场文书
Win10多屏显示如何设置?Win10电脑多屏显示设置操作方法
2022/07/07 数码科技
pnpm对npm及yarn降维打击详解
2022/08/05 Javascript