2011-07-03 48 views
7

我看到this article on polymorphic callable objects,並試圖讓它工作,但它似乎並不是真正的多態,或者至少他們不尊重原型鏈。javascript「polymorphic callable objects」

此代碼打印undefined,而不是"hello there"

此方法不適用於原型,還是我做錯了什麼?

var callableType = function (constructor) { 
    return function() { 
    var callableInstance = function() { 
     return callableInstance.callOverload.apply(callableInstance, arguments); 
    }; 
    constructor.apply(callableInstance, arguments); 
    return callableInstance; 
    }; 
}; 

var X = callableType(function() { 
    this.callOverload = function(){console.log('called!')}; 
}); 

X.prototype.hello = "hello there"; 

var x_i = new X(); 
console.log(x_i.hello); 
+1

我剛剛對你的肖像和名字印象深刻。我想他的名字舒仁周。 – xis

回答

6

你需要改變這一點:

var X = callableType(function() { 
    this.callOverload = function(){console.log('called!')}; 
}); 

這樣:

var X = new (callableType(function() { 
    this.callOverload = function(){console.log('called!')}; 
})); 

通知的new以及圍繞callableType調用括號。

圓括號允許調用callableType並返回該函數,該函數用作new的構造函數。


編輯:

var X = callableType(function() { 
    this.callOverload = function() { 
     console.log('called!') 
    }; 
}); 

var someType = X();  // the returned constructor is referenced 
var anotherType = X(); // the returned constructor is referenced 

someType.prototype.hello = "hello there"; // modify the prototype of 
anotherType.prototype.hello = "howdy";  // both constructors 

var some_i = new someType();   // create a new "someType" object 
console.log(some_i.hello, some_i); 

var another_i = new anotherType();  // create a new "anotherType" object 
console.log(another_i.hello, another_i); 

someType();  // or just invoke the callOverload 
anotherType(); 

我真的不知道如何/在哪裏/爲什麼你會使用這個模式,但我想有一些很好的理由。

+0

也許我做錯了什麼,但這似乎打破了能夠調用實例調用'x_i()'拋出一個異常沿「對象不功能」的行。 –

+0

@luxun:通過像這樣內聯使用'new',您可以立即調用從'callableType'返回的函數作爲構造函數。我認爲你所缺少的是你的代碼被添加到'X'的原型而不是從'X'返回的構造函數。按照我的方式,'X'本身就是構造函數,但是您可以用另一個變量來引用它。我將添加更新。 – user113716

+0

好的,我明白了。我實際上認爲它會使*實例*可調用,但我認爲情況並非如此。 –