2012-05-14 33 views
1

我試圖重寫對象的方法,但仍使用Object.getPrototypeOf()調用原型的原始方法。這在第一次很好,但如果這個方法被重寫超過一次就會出現問題。調用原型的重寫方法,然後調用下一個原型的重寫方法錯誤

此代碼導致堆棧溢出:

A = 
{ 
    blurg: function() 
    { 
     puts('hey there') 
    } 
} 

B = (function buildB(){ 
    var obj = Object.create(A) 

    obj.blurg = function() 
    { 
     Object.getPrototypeOf(this).blurg.apply(this, arguments) 

     puts('hai!!!!') 
    } 

    return obj 
})() 

b = (function buildb(){ 
    var obj = Object.create(B) 

    obj.blurg = function() 
    { 
     Object.getPrototypeOf(this).blurg.apply(this, arguments) 

     puts('bye bye') 
    } 

    return obj 
})() 


b.blurg() 

jsFiddle

的問題是,我想打電話給原型的方法與當前對象爲this。當該方法執行相同的操作時,這會導致問題。

我該怎麼做呢?有沒有一種方法可以創建輔助函數來確保正確的原型被拉起?我有點茫然。

+0

相關:http://stackoverflow.com/questions/6827989/code-re-use-through-javascript-prototypal-inheritance – donut

回答

3

問題是,在JavaScript中,性質上,this總是指原型鏈中的底部向下對象實例,因此當您像上面那樣覆蓋分層結構中的方法時,this.prototype.someMethod()引用對象的確切基類實例中,當您最多有兩個層次的層次時,它似乎並不是一個問題,但是當您定義三層或更多層次結構時,遞歸是不可避免的!方法如下:

A: grand super class 
B: super class - inherits from A (B.prototype = A) 
C: class - inherits from B (C.prototype = B) 

a: instance of A (defines someMethod) 
b: instance of B (defines someMethod, calls A.someMethod through Object.getPrototypeOf(this)) 
c: instance of C (defines someMethod, calls B.someMethod through Object.getPrototypeOf(this)) 

b.someMethod被調用時,它可以成功地調用A的的someMethod(B當叫Object.getPrototypeOf(this)回報A)

然而,當c.someMethod被調用時,它首先調用b.someMethod,進而調用b.someMethod因爲Object.getPrototypeOf(this)在被c調用時總是返回B!這裏發生堆棧溢出。

要解決這個問題,嘗試存儲時,你定義一個新的子類的基類的參考,避免調用超類方法在使用this

A = 
{ 
    blurg: function() { 
     console.log('hey there') 
    } 
}; 

B = (function buildB() { 
    var obj = Object.create(A); 
    var base = Object.getPrototypeOf(obj); 

    obj.blurg = function() { 
     base.blurg.apply(this, arguments); 
     console.log('hai!!!!') 
    } 

    return obj 
})(); 

C = (function buildb() { 
    var obj = Object.create(B); 
    var base = Object.getPrototypeOf(obj); 

    obj.blurg = function() { 
     base.blurg.apply(this, arguments); 
     console.log('bye bye'); 
    } 

    return obj 
})(); 

C.blurg(); 
+0

謝謝!你的解釋比我做得更優雅。存儲「基類」參考比我想象的要簡單得多。現在,是否有更「原型」的方式呢?就像這個解決方案一樣簡單,它看起來有點破綻或暗示我正在以錯誤的方式處理事情。 – donut

相關問題