关于setInterval和setTImeout中的this指向问题
问题描述
前些天在练习写一个小例子的时候用到了定时器,发现在setInterval和setTimeout中传入函数时,函数中的this会指向window对象,如下例:
var num = 0; function Obj (){this.num = 1,this.getNum = function(){console.log(this.num);},this.getNumLater = function(){setTimeout(function(){console.log(this.num);}, 1000)} } var obj = new Obj; obj.getNum();//1 打印的是obj.num,值为1 obj.getNumLater()//0 打印的是window.num,值为0
问题原因
从上述例子中可以看到setTimeout中函数内的this是指向了window对象,这是由于setTimeout()调用的代码运行在与所在函数
完全分离的执行环境上。这会导致这些代码中包含的 this
关键字会指向 window
(或全局
)对象。详细可参考MDN setTimeout
解决方法
若想要让setTimeout中的this指向正确的值,可以使用以下三种比较常用的方法来使this指向正确的值:
1.将当前对象的this存为一个变量,定时器内的函数利用闭包来访问这个变量,如下:
var num = 0; function Obj (){var that = this; //将this存为一个变量,此时的this指向objthis.num = 1,this.getNum = function(){console.log(this.num);},this.getNumLater = function(){setTimeout(function(){console.log(that.num); //利用闭包访问that,that是一个指向obj的指针}, 1000)} } var obj = new Obj; obj.getNum();//1 打印的是obj.num,值为1 obj.getNumLater()//1 打印的是obj.num,值为1
这种方法是将当前对象的引用放在一个变量里,定时器内部的函数来访问到这个变量,自然就可以得到当前的对象。
2.利用bind()方法
var num = 0; function Obj (){this.num = 1,this.getNum = function(){console.log(this.num);},this.getNumLater = function(){setTimeout(function(){console.log(this.num);}.bind(this), 1000) //利用bind()将this绑定到这个函数上} } var obj = new Obj; obj.getNum();//1 打印的为obj.num,值为1 obj.getNumLater()//1 打印的为obj.num,值为1
bind()方法是在Function.prototype上的一个方法,当被绑定函数执行时,bind方法会创建一个新函数,并将第一个参数作为新函数运行时的this。在这个例子中,在调用setTimeout中的函数时,bind方法创建了一个新的函数,并将this传进新的函数,执行的结果也就是正确的了。关于bind方法可参考 MDN bind
3. 箭头函数
var num = 0; function Obj (){this.num = 1,this.getNum = function(){console.log(this.num);},this.getNumLater = function(){setTimeout(() => {console.log(this.num);}, 1000) //箭头函数中的this总是指向外层调用者,也就是Obj} } var obj = new Obj; obj.getNum();//1 打印的是obj.num,值为1 obj.getNumLater()//1 打印的是obj.num,值为1
ES6中的箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj,因此利用箭头函数就可以轻松解决这个问题。
以上三种方法都是比较常用的,当然如果使用call或apply方法来代替bind方法,得到的结果也是正确的,但是call方法会在调用之后立即执行,那样也就没有了延时的效果,定时器也就没有用了,所以推荐使用上述方法来将this传进setTimeout和setInterval中。
转载于:https://www.cnblogs.com/kid526940065/p/10912524.html
关于setInterval和setTImeout中的this指向问题相关推荐
- 关于setTimeout函数中的this指向问题
为什么setTimeout函数的延迟执行函数中this指向window,但是延迟执行函数是箭头函数this指向obj? 根据下面的两点原因解释,foo和foo2中的this都指向obj,但是其中set ...
- 普通函数和箭头函数中的this指向
普通函数的this指向Window function a(){console.log(this) } a() //Window Dom元素绑定事件时的this,句柄里的 this 值是该元素的引用 d ...
- html 取消settimeout,JavaScript中停止执行setInterval和setTimeout事件的方法
js 代码中执行循环事件时,经常会用到 setInterval 和 setTimeout 这两个方法,关于这两个方法的细节这里不详细讨论了,简要分享下在需要停止循环事件的时候该如何操作. (1)set ...
- js中setInterval与setTimeout的区别
一.setInterval与setTimeout的区别 1.setInterval setInterval() 方法可按照指定的周期来调用函数(以毫秒为单位) 语法: setInterval(函数表达 ...
- JS中setInterval、setTimeout不能传递带参数的函数的解决方法
setInterval 和 setTimeout 这两个函数比较好用,但会遇到比如说我隔个几秒后要执行的函数是带参数的,这种情况怎么办?可以用匿名函数包装处理 //不带参数的函数function te ...
- 理解JavaScript中this的指向详解
this的定义和理解: this是JavaScript语言的一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内使用. 1.this和执行环境对象有关,和函数的声明无关. var ...
- setInterval和setTimeout
setInterval和setTimeout 1. 总结 1.1. setTimeout和setInterval()的时间间隔是不可动态修改的 1.1.1. 错误方式 1.1.2. 正确方式 1.2. ...
- 简述JS中THIS的指向?
这里是修真院前端小课堂,每篇分享文从 八个方面深度解析前端知识/技能,本篇分享的是: [简述JS中THIS的指向?] 大家好,我是IT修真院武汉分院web第16期的学员孟晨,一枚正直纯洁善良的web程 ...
- JS中this的指向与改变this指向的三个方法
目录 一.this指向的分类 1.全局函数的调用 2.对象中函数的调用 3.setTimeout与setInterval中的this 4.事件绑定中的this 5.箭头函数中的this 6.构造函数中 ...
最新文章
- PHP与Python哪个做网站产品好?
- QString和string互相转换乱码处理
- 【译】Using Machine Learning to Understand the Ethereum Blockchain
- Process和ProcessBuilder入门【原】
- 17、【 商品管理模块开发】——后台商品图片的springmvc和富文本上传以及ftp文件服务器的开发...
- 通过NSNotification来监听键盘弹出和弹回
- TVM:使用 Schedule 模板和 AutoTVM 来优化算子
- 注解 @CrossOrigin
- mysql 主主忽略错误_MySQL 主主报错: Fatal error: The slave I/O thread stops because master and slave have...
- [翻译]自定义Sharepoint的登陆页面
- [转载] python中list与string的转换
- 勒索病毒 -- “永恒之蓝”NSA 武器免疫工具
- 分享100个好看且实用的PPT模板
- 用java求可达矩阵_ISM算法(邻接矩阵求可达矩阵)Java实现
- 正则表达式的语法汇总
- python怎么加字幕_使用moviepy为电影添加字幕
- 百位LOL英雄联盟角色合集
- 虚拟化开源技术有哪些_您使用哪些开源虚拟化工具?
- 零跑股价再度上涨的原因到底是什么呢?
- 10个非常适合菜鸟练手的Python项目,墙裂建议收藏!
热门文章
- spring boot 教程(三)配置详解
- 如何设置电脑自动锁屏_办公族如何设置自动关闭显示器,让显示屏锁屏,防止偷看你电脑。...
- android volley 请求参数,android – Volley – 如何发送DELETE请求参数?
- Leetcode-213:打家劫舍 II
- 系统学习NLP(十二)--文本表示综述
- python 矩量法_矩量法:β二项分布
- azure kinect三维点云_三维重建技术,你捋清楚了吗?本文适合小白
- hive窗口函数入门
- Windows核心编程_窗口蒙版效果
- centos7---mysql5.7主从复制读写分离