【知识】定时器setTimeout/setInterval执行时this指针指向问题
【问题描述】
setTimetout/setInterval中this指针指向window,以下是一个小demo:
var demoChange = { key: true, changeFun() { console.log('调用函数'); this.key = true; }, init() { setInterval(function () { if (this.key) { // 此处会报出this.key is undefined 的错误 this.key = false; this.changeFun(); } }, 3000); } } demoChange.init();
我想要的是this指定demoChange对象,但是function中的this指向的是window。
【解决方案】
1、保存this变量
var demoChange = { key: true, changeFun() { console.log('调用函数'); this.key = true; }, init() { var _this = this; // init()函数由对象调用,因此this指向对象 setInterval(function () { if (_this.key) { //闭包原理 函数内部找不到_this变量,会向父级作用域找 _this.key = false; _this.changeFun(); } }, 3000); } } demoChange.init();
2、改变函数内部this指向:bind
var demoChange = { key: true, changeFun() { console.log('调用函数'); this.key = true; }, init() { setInterval(function () { if (this.key) { this.key = false; this.changeFun(); } }.bind(this), 3000); // bind会将第一个参数替换函数内的this指向,这里不用call/aplly是因为它们会立即执行函数,而bind不会。 } } demoChange.init();
3、箭头函数
var demoChange = { key: true, changeFun() { console.log('调用函数'); this.key = true; }, init() { setInterval(() => { // 箭头函数内没有this指向问题,this会使用父级作用域中的this if (this.key) { this.key = false; this.changeFun(); } }, 3000); } } demoChange.init();
【参考文章】https://www.cnblogs.com/zsqos/p/6188835.html