2011-12-22 53 views
2

我使用原型在JavaScript中定義了''。第一次func()運行時,它可以工作,但是當它第二次通過setTimeout調用時,它會失敗,因爲這次它失去了對象上下文I.E. 不再引用該對象,但現在引用窗口將樣機的功能作爲參數傳遞而不會丟失'this'背景

有沒有一種方法可以克服這個問題,同時仍然使用原型?還是我需要使用閉包來定義''?

function klass(){} 

klass.prototype = { 
    a: function() { 
    console.log("Hi"); 
    },  
    func: function(){ 
    this.a(); 
    setTimeout(this.func, 100); 
    } 
}; 

var x = new klass(); 
x.func(); 
+2

僅供參考函數沒有自己的任何方面,解決了每一個函數被調用,並只對通話時間。因此,函數的定義在何處以及如何定義並不重要,它只關心函數在特定時間的調用方式。 'x.func()'函數被稱爲'x'的屬性。 'var y = {func:x.func}; y.func()'該函數被稱爲'y'的屬性,'this'則被稱爲'y'。看看我要去哪裏? setTimeout總是調用窗口設置爲this的函數。 – Esailija 2011-12-22 22:23:33

+0

[JavaScript Callback Scope]的可能重複(http://stackoverflow.com/questions/183214/javascript-callback-scope) – 2011-12-22 22:29:26

回答

6

使用Function.prototype.bind

setTimeout(this.func.bind(this), 100); 

從Mozilla開發者網絡:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

if (!Function.prototype.bind) { 
    Function.prototype.bind = function (oThis) { 
    if (typeof this !== "function") { 
     // closest thing possible to the ECMAScript 5 internal IsCallable function 
     throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 
    } 

    var aArgs = Array.prototype.slice.call(arguments, 1), 
     fToBind = this, 
     fNOP = function() {}, 
     fBound = function() { 
      return fToBind.apply(this instanceof fNOP 
           ? this 
           : oThis || window, 
           aArgs.concat(Array.prototype.slice.call(arguments))); 
     }; 

    fNOP.prototype = this.prototype; 
    fBound.prototype = new fNOP(); 

    return fBound; 
    }; 
} 
+0

這裏有一個重要的考慮因素:這隻適用於ECMAScript 5實現的瀏覽器。這意味着只有新瀏覽器才能正常工作:FF4 +,IE9 + – Jonathan 2012-04-16 13:08:47

+1

相反,它只是內置在這些瀏覽器上。否則可以使用上述定義。 – 2012-04-16 16:58:58

3

您可以在一個功能包裝它:

var self = this; // reference the value of "this" 

setTimeout(function() {self.func();}, 100); 
2

使用Function.prototype.bind,或包裝你setTimeout回調在自己的封:

func: function() { 
     var self = this; 
     self.a(); 
     setTimeout(function() { 
      self.func(); 
     }, 100); 
    } 
相關問題