2011-12-16 56 views
9

我想猴子修補這個'Controller'對象的構造函數。但是,我怎樣才能修補構造函數,以便我仍然可以調用原始函數?這是我試過的。如何修補對象的構造函數?

// original 
function Controller() { 
    this._tag = 'div'; 
} 
Controller.prototype.tag = function() { 
    console.log(this._tag); 
} 

var c = new Controller(); 
c.tag(); // -> 'div', as expected 


// patch attempt 
var original = Controller; 
Controller = function() { 
    original.apply(this); 
    this._tag = 'patched'; // patch 
} 

var c = new Controller(); 
c.tag(); // no method tag, prototype appears wiped... 
+0

圍繞RHS函數表達式的分組運算符是多餘的。 「構造函數」是在另一個函數內聲明的,所以你不能從外部訪問它(除非缺少代碼使它成爲外部匿名函數或其他對象的屬性)。所以如果你想要「修補」構造函數(無論這意味着什麼),插入代碼的地方你的評論是唯一的方法。 – RobG 2011-12-16 06:37:12

+0

@RobG如果好奇:http://en.wikipedia.org/wiki/Monkey_patch它非常簡單直接地爲猴子修補一個屬性或方法,但由於構造函數的特殊狀態,我很茫然。你可能是正確的,這是不可能的,但我不確定你說的原因。我會更新代碼示例以反映。 – 2011-12-16 15:03:56

+0

添加了更好的代碼示例。 – 2011-12-16 15:48:28

回答

8

你似乎想要做的事,如:

Constructor.prototype.oldTag = Constructor.prototype.tag; 

Constructor.prototype.tag = function() {/* whatever */}; 

現在所有情況下獲得新的標籤方法如果你想(或放回),你仍然可以撥打oldTag

或者你想要做的事,如:

var oldConstructor = Constructor; 

var Constructor = function() { /* new constructor */ }; 
Constructor.prototype = oldConstructor.prototype; 

所以,現在你有所有的老方法一個新的構造。或者做以上兩件事。只需用簡單的英語說出你想要做什麼。

2

清潔器的方法是不猴修補的構造:把構造邏輯在一個單獨的init方法和猴補丁/繼承代替。

function Constructor(){ 
    this.init(); 
} 
Constructor.prototype.init = function(){ /*...*/ }; 

你也可以考慮建立對象與設計器功能

function make_fancy_obj(){ 
    var obj = new Constructor(); 
    obj.foo = 'bar'; 
    return obj; 
}