指定我有一個類層次結構像類名的對象:的Node.js - 創建變量
|-> Square
AbstractShape -+-> Circle
|-> Triangle
現在,我想實現的戰略格局,並創建一個儲存在String類的一個對象。在PHP中,我會使用:
$type = 'Square';
$obj = new $type();
Node.js中是否有等價物?
指定我有一個類層次結構像類名的對象:的Node.js - 創建變量
|-> Square
AbstractShape -+-> Circle
|-> Triangle
現在,我想實現的戰略格局,並創建一個儲存在String類的一個對象。在PHP中,我會使用:
$type = 'Square';
$obj = new $type();
Node.js中是否有等價物?
如果你希望有一個更強大和可測試的方式去,你可以使用類和工廠模式的組合來發布對象。看看下面的內容,你會發現,通過這種設置,包括更細粒度的邏輯和測試的方式將變得更加容易,併爲您提供更大的靈活性。你也在抽象出.issue
電話背後的新對象 - 這在某些情況下可能是有益和方便的。
我也注意到你提到你的PHP背景,所以我還展示了一些ES6中面向對象的方法。
class AbstractShape {
constructor(type) {
this.type = type;
}
getType() {
console.log(`I am a ${this.type}`);
}
}
class Square extends AbstractShape {
constructor(type) {
super(type);
this.sides = 4;
}
getDescription() {
console.log(`I have ${this.sides} equal sides`);
}
}
class ShapeFactory {
static issue(type) {
switch(type) {
case 'Square': return new Square(type);
break;
case 'Circle': /* same pattern with a Circle class */
break;
}
}
}
let shape = ShapeFactory.issue('Square');
shape.getType(); /* I am a Square */
shape.getDescription(); /* I have 4 equal sides */
JSFiddle Link - 演示
此外,如果你想要的東西多一點故障不是處理例如冗餘容錯串'Square'
- there are some creative ways可以利用枚舉類方法來進一步優化。我將在這裏保存房地產,而不是重新編碼代碼片段,但將包括一個小提琴讓你檢查。
JSFiddle Link - 枚舉的方法演示
快速和骯髒的方法是使用eval
。但是,強烈不推薦的,因爲很多的原因 - 安全,性能,可讀性,可支持
function MyType() {
}
var typeName = 'MyType';
var typeObj = eval('new ' + typeName + '()');
更安全,更正確的比eval
是使用字符串名稱映射到類型(感謝@GaloisGecko)
function createType(name) {
var types = {
"Square": Square,
"Circle": Circle,
"Triangle": Tringle
};
return types.hasOwnProperty(name) ? new types[name]() : null;
}
最後,最好的和明智的決定是應用工廠模式。見@scniro answer。你也可以找到很好的說明和示例here
只要有可能就不要使用'eval'。在這裏你不需要,所以遠離這個解決方案。 –
安全的方式將定義一個工廠對象:
function Square() {
}
// here other constructors for Circle and Triangle
var factory = {
"Square": Square,
"Circle": Circle,
"Triangle" : Triangle
}
var typeName;
// here some code which sets typeName
var typeObj = new factory[typeName]();
經仔細考慮有周圍Node.js的相當簡單的方法 當你以最簡單的方式實例化一個對象時,你實際上編寫了new <variableName>
,其中variableName
是一些在某些模塊中定義和導出的函數或類的主體。把這個函數/類分配給變量你require()
吧。
所以,與其
const type = 'Square';
const aSquare = new type();
你需要寫:
const type = 'Square';
const shape = require(`${pathToShapeModules}/${type}.js`);
const aShape = new shape();
小缺點是eslint抱怨(在某些規則的設置),其require
s爲要放置在頂部模塊。當然,它需要通過try ... catch等適當的異常處理,所以可能Factory解決方案更好(所以我會接受它),但我認爲對於小型專業案例,這種解決方案是可以的。
它就像調用'new Square()' – zabusa