国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解JS中定時器setInterval和setTImeout的this指向問題

2019-11-19 18:06:11
字體:
來源:轉載
供稿:網友

前言

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,值為1obj.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,值為1obj.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,值為1obj.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,值為1obj.getNumLater()//1  打印的為obj.num,值為1

bind()方法是在Function.prototype上的一個方法,當被綁定函數執行時,bind方法會創建一個新函數,并將第一個參數作為新函數運行時的this。在這個例子中,在調用setTimeout中的函數時,bind方法創建了一個新的函數,并將this傳進新的函數,執行的結果也就是正確的了。關于bind方法可參考 MDN bind

以上兩種方法都是比較常用的,當然如果使用call或apply方法來代替bind方法,得到的結果也是正確的,但是call方法會在調用之后立即執行,那樣也就沒有了延時的效果,定時器也就沒有用了,所以推薦使用上述兩種方法來將this傳進setTimeout和setInterval中。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 孟村| 个旧市| 桐庐县| 曲周县| 辽中县| 民和| 明水县| 广汉市| 张掖市| 格尔木市| 庆安县| 日喀则市| 仪陇县| 泸州市| 苏尼特右旗| 正镶白旗| 始兴县| 吉安县| 平谷区| 清新县| 扎赉特旗| 吉水县| 吉安市| 娄底市| 万盛区| 梁河县| 邯郸县| 昌都县| 红原县| 漳平市| 黎川县| 柳林县| 开鲁县| 西昌市| 霍州市| 梁平县| 枣阳市| 蓬安县| 惠来县| 枣阳市| 阳新县|