-
使用js中的定時器(setInterval译打,setTimeout)佑淀,很容易會遇到this指向的問題留美。
例如:var name = 'my name is window';
var obj ={
name:'my name is obj',
fn:function(){
var timer = null;
clearInterval(timer);
timer = setInterval(function(){
console.log(this.name)//my name is window
},1000)
}
}在這里,從this.name可以看出this的指向是window。
如果沒有特殊指向独榴,setInterval和setTimeout的回調(diào)函數(shù)中this的指向都是window僧叉。這是因為JS的定時器方法是定義在window下的奕枝。但是平時很多場景下棺榔,都需要修改this的指向。這里總結(jié)了幾種:
-
最常用的方法:在外部函數(shù)中將this存為一個變量隘道,回調(diào)函數(shù)中使用該變量症歇,而不是直接使用this。
var name = 'my name is window'; var obj ={ name:'my name is obj', fn:function(){ var that = this; var timer = null; clearInterval(timer); timer = setInterval(function(){ console.log(that.name)//my name is obj },1000) } }
在fn中加了var that = this; 回調(diào)函數(shù)中使用that代替this即可谭梗。這種方法最常見忘晤,使用也最廣泛。
-
使用bind()方法(bind()為ES5的標準激捏,低版本IE下有兼容問題设塔,可以引入es5-shim.js解決)。
bind()的作用類似call和apply远舅,都是修改this指向闰蛔。但是call和apply是修改this指向后函數(shù)會立即執(zhí)行,而bind則是返回一個新的函數(shù)图柏,它會創(chuàng)建一個與原來函數(shù)主體相同的新函數(shù)序六,新函數(shù)中的this指向傳入的對象。var name = 'my name is window'; var obj = { name: 'my name is obj', fn: function () { var timer = null; clearInterval(timer); timer = setInterval(function () { console.log(this.name); //my name is obj }.bind(this), 1000) } }
在這里為什么不能用call和apply蚤吹,是因為call和apply不是返回函數(shù)例诀,而是立即執(zhí)行函數(shù),那么裁着,就失去了定時器的作用
-
使用es6的箭頭函數(shù):箭頭函數(shù)的最大作用就是this指向繁涂。
var name = 'my name is window'; var obj = { name: 'my name is obj', fn: function () { var timer = null; clearInterval(timer); timer = setInterval(() => { console.log(this.name); //my name is obj }, 1000) } }
箭頭函數(shù)沒有自己的this,它的this繼承自外部函數(shù)的作用域二驰。所以扔罪,在該例中,定時器回調(diào)函數(shù)中的this诸蚕,是繼承了fn的this步势。當然箭頭函數(shù)也有兼容問題,要是兼容低版本ie背犯,需要使用babel編譯坏瘩,并且引入es5-shim.js才可以。