2010-07-20 63 views
1

我新的基於原型的語言,並已閱讀了這個問題:使用基於原型簽名附加方法的對象的Javascript原型綁定

Preserving a reference to "this" in JavaScript prototype functions

我想知道什麼價值存在, 。爲什麼不把方法附加到對象定義中的對象的屬性?

其次,當使用原型簽名來定義對象上的方法時,爲什麼'this'指針會解析到函數內部的窗口對象?這似乎是一個設計缺陷。如果不是有人可以解釋,或者指出我爲什麼不解釋?

謝謝。

編輯:

如預期,呈現一個消息框,字「這裏」這裏面的代碼執行。

function Obj() 
{ 
    this.theVar = 'here'; 
    this.method2 = function(){ alert(this.theVar); } 
} 

Obj.prototype.method3 = function(){ this.method2(); } 
Obj.prototype.method4 = function(){ this.method3(); } 

var obj = new Obj(); 
obj.method4(); 

此代碼是我的AJAX回調函數,'this'指針指向執行期間的'window'對象。

Test.prototype.nextCallback = function(response) 
{ 
    if(response.Status != 'SUCCESS') 
     show_message(response.Message, false); 
    else 
     this.setQuestion(response.Question); 
} 

Test.prototype.setQuestion = function(question){ ... } 

'this'指針實際上在AJAX調用之前正常工作,但不在之後。這是否是因爲在AJAX調用返回之後且在調用回調之前nextCallback()上下文未正確恢復?有沒有辦法來解決這個問題?

+0

我不認爲你的意思是'原型簽名' - 你說的是原型屬性不是嗎? – Skilldrick 2010-07-20 21:20:32

+0

「原型簽名」我的意思是定義一個像這樣的方法: myObj.prototype.myFunction = function(){...} – 2010-07-20 21:24:36

回答

1

1-在構造函數的原型上添加成員的重點是行爲重用。

所有對象實例,從該原型繼承,就能決心通過原型鏈成員,也是各位的定義只有一次,而不是在每一個實例。

2-這是因爲每個功能都有它自己的執行上下文(這是this值的存儲位置),並且當調用一個函數的this值被隱式設置,並且如果一個函數引用沒有基礎對象 (例如,foo();obj.foo()),全局對象將在被調用的方法內設置爲this值。

有關更多詳細信息,請參閱this answer的第二部分。

編輯:找你的代碼之後,似乎要傳遞的nextCallback方法,一些Ajax成功事件的回調函數的引用,如果是這樣,參考的基礎對象將丟失,共同方法可以是使用正確調用你的方法匿名函數,例如:

var obj = new Test(); 
//... 
someAjaxLib(url, function (data) { 
    obj.nextCallback(data); // `this` will refer to obj within nextCallback 
}); 

另一種方法可以是在構造函數中綁定到其實例的方法,請記住,該方法將被定義爲一個自己的財產你創建的每個對象實例,它不會被繼承,例如:

function Test() { 
    var instance = this; // store reference to the current instance 

    this.nextCallback = function(response) { 
    if(response.Status != 'SUCCESS') { 
     show_message(response.Message, false); 
    } else { 
     instance.setQuestion(response.Question); // use the stored reference 
    } 
    } 
} 
+0

感謝您回覆CMS。您似乎對該主題有深入的瞭解,並且希望發佈更多的代碼,告訴您我正在努力完成的任務。我會在下面發佈一個答案,以便它更具可讀性。 – 2010-07-20 22:28:04

+0

@Andrew,我看過你的代碼,看看我的迴應。 – CMS 2010-07-20 23:10:03

+0

我同意。請參閱下面的答案。 – 2010-07-20 23:17:41

0
  1. 在JavaScript中,如果你使用一個函數作爲一個構造函數,以創建新的對象,然後在構造函數分配方法this意味着每個新對象獲取定義的新方法。分配給原型意味着您只能在原型中獲得該方法的一個定義。

  2. 是的,this在某些情況下指向全局對象是一個設計缺陷,但我沒有想到在這種情況下你提到這種情況。

如果您想了解JavaScript對象和原型繼承的最佳實踐,請觀看Douglas Crockford's videos

+0

謝謝Skilldrick,我一定會看看這些視頻。 – 2010-07-20 22:28:29

0

在我的情況出現,當該方法是通過一個原型簽名添加到對象,並隨後通過用作AJAX回調方法,該方法然後重新作用域到全局對象(窗口)並丟失其原始上下文。也就是說,該方法不再是其定義的原型的成員。

我只在Firefox中測試過。我猜這種行爲是因爲AJAX調用是在不同的OS線程上物理執行的,並且從AJAX調用返回後,找到並執行指定的回調方法。沒有嘗試解決線程之間方法的原始上下文。這再次只是一個猜測。

+0

它必須做的是如何調用方法,因爲你只傳遞一個引用,Ajax庫通常會調用一個參數,沒有任何基礎對象信息,例如:'var t = new Test(),m = t .nextCallback; m();'在前面的例子中,'m'指的是方法,就像將它作爲參數傳遞一樣,調用'm();'將'this'值設置爲全局對象。 – CMS 2010-07-20 23:27:00