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 相关文章推荐
关于可运行代码无法正常执行的使用说明
May 13 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
Nov 29 Javascript
玩转方法:call和apply
May 08 Javascript
Node.js中HTTP模块与事件模块详解
Nov 14 Javascript
JQuery显示、隐藏div的几种方法简明总结
Apr 16 Javascript
javascript实现将数字转成千分位的方法小结【5种方式】
Dec 11 Javascript
关于meta viewport中target-densitydpi属性详解(推荐)
Aug 18 Javascript
浅谈JS中this在各个场景下的指向
Aug 14 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
Sep 06 Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
May 01 Javascript
浅谈nuxtjs校验登录中间件和混入(mixin)
Nov 06 Javascript
详解Vue slot插槽
Nov 20 Vue.js
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.MVC的模板标签系统(二)
2006/09/05 PHP
php中OR与|| AND与&&的区别总结
2013/10/26 PHP
thinkphp路由规则使用示例详解和伪静态功能实现(apache重写)
2014/02/24 PHP
smarty中改进truncate使其支持中文的方法
2016/05/30 PHP
PHP laravel中的多对多关系实例详解
2017/06/07 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
JavaScript 异步调用框架 (Part 5 - 链式实现)
2009/08/04 Javascript
JavaScript 权威指南(第四版) 读书笔记
2009/08/11 Javascript
php gethostbyname获取域名ip地址函数详解
2010/01/24 Javascript
utf-8编码引起js输出中文乱码的解决办法
2010/06/23 Javascript
JS 实现完美include载入实现代码
2010/08/05 Javascript
javascript实现鼠标拖动改变层大小的方法
2015/04/30 Javascript
JavaScript截断字符串的方法
2015/07/15 Javascript
JQuery实现的按钮倒计时效果
2015/12/23 Javascript
Backbone View 之间通信的三种方式
2016/08/09 Javascript
ES6中Generator与异步操作实例分析
2017/03/31 Javascript
深入浅析ES6 Class 中的 super 关键字
2017/10/20 Javascript
Bootstrap4如何定制自己的颜色和风格
2018/02/26 Javascript
Vue实现侧边菜单栏手风琴效果实例代码
2018/05/31 Javascript
vue 实现数字滚动增加效果的实例代码
2018/07/06 Javascript
js实现缓动动画
2020/11/25 Javascript
JS闭包原理及其使用场景解析
2020/12/03 Javascript
[04:38]完美世界携手游戏风云打造 卡尔工作室饰品系统篇
2013/04/25 DOTA
Python ORM框架SQLAlchemy学习笔记之数据查询实例
2014/06/10 Python
python中requests模块的使用方法
2015/04/08 Python
python安装与使用redis的方法
2016/04/19 Python
python可视化text()函数使用详解
2020/02/11 Python
Keras自定义IOU方式
2020/06/10 Python
python 实现学生信息管理系统的示例
2020/11/28 Python
css3实现圆锥渐变conic-gradient效果
2020/02/12 HTML / CSS
祖国在我心中演讲稿450字
2014/09/05 职场文书
英文自荐信范文
2015/03/25 职场文书
《给予树》教学反思
2016/03/03 职场文书
微信小程序实现录音Record功能
2021/05/09 Javascript
Pycharm 如何设置HTML文件自动补全代码或标签
2021/05/21 Python
MySQL 数据库 增删查改、克隆、外键 等操作
2022/05/11 MySQL