在js中setTimeout和setInterval都是用來定時的一個功能,下面這篇文章主要給介紹了JS中setInterval和setTImeout的this指向問題,文中通過示例介紹的很詳細,有需要的朋友可以參考借鑒,一起來看看吧,
前言
Js是一個單執行緒語言,可以通過setTimeout()和setInterval()來設定代碼在指定時刻運行,前者是在指定時間后執行,后者是指每隔一段時間執行,兩者的使用方法類似,
最近在練習寫一個小例子的時候用到了定時器,發現在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則指向當前物件,如下例:
var num = 0;
function Obj (){
this.num = 1,
this.getNum = function(){
console.log(this.num);
},
this.getNumLater = function(){
setTimeout(console.log(this.num), 1000)
}
}
var obj = new Obj;
obj.getNum();//1 列印的為obj.num,值為1
obj.getNumLater()//1 列印的為obj.num,值為1
從以上兩個例子可以看出,當在setTimeout中傳入的引數為函式時,函式內部的this才會指向window物件,
當在setTimeout中傳入了一個函式,若想要讓this指向正確的值,可以使用以下兩種比較常用的方法來使this指向正確的值:
1.將當前物件的this存為一個變數,定時器內的函式利用閉包來訪問這個變數
如下:
var num = 0;
function Obj (){
var that = this; //將this存為一個變數,此時的this指向obj
this.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
以上兩種方法都是比較常用的,當然如果使用call或apply方法來代替bind方法,得到的結果也是正確的,但是call方法會在呼叫之后立即執行,那樣也就沒有了延時的效果,定時器也就沒有用了,所以推薦使用上述兩種方法來將this傳進setTimeout和setInterval中,
本文轉載于腳本之家,作者:陌路黃昏后 的文章,原文鏈接:https://m.jb51.net/article/102232.htm
如有侵權,請告知洗掉
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/36859.html
標籤:JavaScript
