2013-11-26 29 views
2

我有兩個簡單的鏈接,點擊時應該等待一秒鐘,然後添加一個類來改變文本的顏色。工作版本使用$.proxy和我試圖使用本地JavaScript來更改this的含義的非工作版本。爲什麼btnWaitNoProxy這仍然指的是全局對象?JavaScript setTimeout,使用調用來改變這

fiddle

代碼:

var obj = { 
      wait: function() { 
       setTimeout(function() { 
        console.log('inside the setTimeout'); 
        $(this).addClass('lesson'); 
        //refers to global object in the console 
       }, 1000); 
      } 
     }; 

$('#btnProxy').on('click', function() { 
      console.log('preparing to add class...'); 
      setTimeout($.proxy(function() { 
       $(this).addClass('lesson') 
       console.log(this); 
      }, this), 1000); 
     }); 
     $('#btnWaitNoProxy').on('click', function() { 
      console.log(this); 
      //call still refers to the global object 
      obj.wait.call(this); 
     }); 

回答

2

由於您使用的是waitsetTimeout,所以傳遞給setTimeout該回調方法將在默認情況下,在全球範圍內執行。

一個可能的解決方案是使用$ .proxy(),您已與setTimeout處理器

var obj = { 
    wait: function() { 
     setTimeout($.proxy(function() { 
      console.log('inside the setTimeout'); 
      $(this).addClass('lesson'); 
      //refers to global object in the console 
     }, this), 1000); 
    } 
}; 

另一種是用一個封閉的可變像

var obj = { 
    wait: function() { 
     var self = this; 
     setTimeout(function() { 
      console.log('inside the setTimeout'); 
      $(self).addClass('lesson'); 
      //refers to global object in the console 
     }, 1000); 
    } 
}; 
+0

我想一個燈泡只是爲了我而點擊了,爲什麼要使用'self = this'或'that = this'! :) – wootscootinboogie

0

當您再次完成將方法傳遞給setTimeout()(或其他任何函數),則會調用錯誤的this值。

setTimeout()執行的代碼在一個單獨的執行上下文中運行到它被調用的函數中。因此,被調用函數的this關鍵字將被設置爲窗口(或global)對象;它將不會與調用setTimeout的函數的this值相同。

來源:MDN — window.setTimeout

有很多的解決方案:

  1. 使用$.proxy
  2. 使用Function.prototype.bind
  3. 別名this
相關問題