2012-03-07 74 views
0

我正在處理我的第一個Node.js項目,並且遇到了OOP問題,我不確定Node.js如何解決。Node.js中的參數化模塊加載

我有一個模塊A:

module.exports = A; 

function A() { 
} 
A.prototype.method = function() { return "A";}; 
//other methods... 

和幾個其他的模塊(可以說B和C)實現相同的 「界面」 A.

現在,我有模塊X:

module.exports = X; 

function X(impl) { 
    //choose A, B, or C based on value of impl 
} 

所以現在的問題是,如何實現X,以便能夠做到:

var X = require("x"); 
var impl = new X("A"); 
impl.method(); //returns "A" 

我相信prototype__proto__會涉及?

編輯:我試圖實現的是基於一些字符串值(ENV變量)通過標準化接口new X()加載實現A,B或C,然後通過該方法訪問A(B,C ...)的方法X的實例。

+0

吧?也許它是你的示例代碼,但你似乎沒有理解這是如何工作的。或者我不明白你想要完成什麼。看到我的答案,我認爲你正在嘗試做什麼。 – 2012-03-07 09:48:15

+1

X應該有一個工廠方法,您應該從X.create(A_B_or_C)返回新的A,new Bor new C. – mpm 2012-03-07 11:54:30

回答

2

我覺得這是你追求的:

A.js(B.js和C.js都差不多,當然):

function A() {} 

A.prototype.method = function() { 
    return 'A'; 
}; 

module.exports = A; 

X.js:

var modules = { 
    A: require('./A'), 
    B: require('./B'), 
    C: require('./C') 
} 

function X(impl) { 
    if(impl in modules) 
     return new modules[impl]; 
    else 
     throw new Error('Unknown impl: ' + impl); 
} 

module.exports = X; 

用法:

var foo = new X('A'); 
foo.method(); 
// => 'A' 
var bar = new X('B'); 
bar.method() 
// => 'B' 

的替代方法keepi納克modules對象XrequireX(impl),讓require拋出錯誤:

function X(impl) { 
    return new require('./' + impl); 
} 
+1

這幾乎是我該怎麼做的。另一個可能的改進是,如果你想做自己的錯誤處理,但不想保留一個模塊數組(例如,你計劃經常添加D,E,F等)將使用節點的require.resolve()功能,以確保在實際需要之前存在請求的模塊,而無需在自己的已知模塊陣列中查找它。 – 2012-03-07 19:11:03

+0

我實際上發現你最後一點得到的地方是行不通的。出於某種原因,除非您將其更改爲'function X(impl)var x = new require('./'+ impl); return x; }''foo.method()'會拋出一個錯誤,說對象沒有這個方法。 – 2012-03-08 22:17:25

0
//x.js 
module.exports = function(a) { 
    return a; 
} 

//a.js 
modules.exports = function() { 
return {method: function() { return "A" } }; 
} 

var X = require("x"); 

var impl = new X(require("a")); 

impl.method(); //returns "A" 

是否正確?

+0

好吧,有點。除了我不能調用'impl.method()',因爲它是在A的原型中聲明的。此外,這不會爲X和A調用構造函數。 – 2012-03-07 10:16:13

+0

因爲數據不是強類型的,應該很容易,只需將您的原型作爲參數傳遞給x的require即可,然後您可以返回任何這些類的實例 – 2012-03-07 16:55:57

1

要調用父構造函數,您需要在新對象的上下文中實際調用/應用它。見[1]。

要繼承方法,需要將父類中的原型克隆到子類。參見[2]

// parentclass.js 
var ParentClass = function (arg) { 
    console.log("Calling ParentClass constructor with " + arg); 
}; 

ParentClass.prototype.method = function (arg) { 
    console.log("Calling ParentClass method with " + arg); 
}; 

// childclass.js 
var ChildClass = function() { 
    console.log("Calling ChildClass constructor"); 
    // [1] 
    ParentClass.apply(this, arguments); 
}; 

// [2] 
ChildClass.prototype = Object.create(ParentClass.prototype); 

var instance = new ChildClass('some argument'); 
instance.method('ahahahah'); 

這正是你需要的嗎?

+0

+1解釋 – 2012-03-08 09:20:23

+0

謝謝。哦,我忘了導出'var ParentClass = module.exports = ...'。 – kevin 2012-03-08 13:45:50