Javascript定時器中的this指向


使用js中的定時器(setInterval,setTimeout),很容易會遇到this指向的問題。

直接上例子:

 1 var name = 'my name is window';
 2 var obj = {
 3     name: 'my name is obj',
 4     fn: function () {
 5         var timer = null;
 6         clearInterval(timer);
 7         timer = setInterval(function () {
 8             console.log(this.name);  //my name is window
 9         }, 1000)
10     }
11 }

在這里,從this.name可以看出this的指向是window。

如果沒有特殊指向,setInterval和setTimeout的回調函數中this的指向都是window。這是因為JS的定時器方法是定義在window下的。但是平時很多場景下,都需要修改this的指向。這里總結了幾種:

1、最常用的方法:在外部函數中將this存為一個變量,回調函數中使用該變量,而不是直接使用this。

 1 var name = 'my name is window';
 2 var obj = {
 3     name: 'my name is obj',
 4     fn: function () {
 5         var that = this;
 6         var timer = null;
 7         clearInterval(timer);
 8         timer = setInterval(function () {
 9             console.log(that.name);   //my name is obj
10         }, 1000)
11     }
12 }

在fn中加了var that = this; 回調函數中使用that代替this即可。這種方法最常見,使用也最廣泛。

2、使用bind()方法(bind()為ES5的標准,低版本IE下有兼容問題,可以引入es5-shim.js解決)

bind()的作用類似call和apply,都是修改this指向。但是call和apply是修改this指向后函數會立即執行,而bind則是返回一個新的函數,它會創建一個與原來函數主體相同的新函數,新函數中的this指向傳入的對象。

 1 var name = 'my name is window';
 2 var obj = {
 3     name: 'my name is obj',
 4     fn: function () {
 5         var timer = null;
 6         clearInterval(timer);
 7         timer = setInterval(function () {
 8             console.log(this.name);   //my name is obj
 9         }.bind(this), 1000)
10     }
11 }

在這里為什么不能用call和apply,是因為call和apply不是返回函數,而是立即執行函數,那么,就失去了定時器的作用。

3、使用es6的箭頭函數:箭頭函數的最大作用就是this指向。

 1 var name = 'my name is window';
 2 var obj = {
 3     name: 'my name is obj',
 4     fn: function () {
 5         var timer = null;
 6         clearInterval(timer);
 7         timer = setInterval(() => {
 8             console.log(this.name);  //my name is obj
 9         }, 1000)
10     }
11 }

箭頭函數沒有自己的this,它的this繼承自外部函數的作用域。所以,在該例中,定時器回調函數中的this,是繼承了fn的this。當然箭頭函數也有兼容問題,要是兼容低版本ie,需要使用babel編譯,並且引入es5-shim.js才可以。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM