Node.js - 创建变量中指定的类名对象

问题描述 投票:7回答:4

我有一个类层次结构,如:

               |-> Square
AbstractShape -+-> Circle
               |-> Triangle

现在,我想实现策略模式并创建一个存储在字符串中的类对象。在PHP中我会使用:

$type = 'Square';
$obj = new $type();

Node.js中有等价物吗?

javascript node.js strategy-pattern
4个回答
5
投票

如果您希望采用更强大且可测试的方法,则可以使用类和工厂模式的组合来发布对象。查看以下内容,您将看到通过此设置,包括更精细的逻辑和测试将更容易,并提供更大的灵活性。你也在.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 */

Z zxswでも-but


此外,如果您想要比处理冗余字符串更容错一些,例如JSFiddle Link - 'Square'利用类似枚举的方法,可以进一步完善这一点。我将在这里保存房地产而不是重新哈希代码片段,但会包含一个小提琴供您查看。

there are some creative ways - enum方法演示


5
投票

一种安全的方法是定义工厂对象:

JSFiddle Link

2
投票
  1. 快速而肮脏的方式是使用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](); 。但强烈建议不要使用它,原因很多 - 安全性,性能,可读性和可支持性 eval
  2. function MyType() { } var typeName = 'MyType'; var typeObj = eval('new ' + typeName + '()'); 更安全和更正确的是使用字符串名称到类型的映射(感谢@GaloisGecko) eval
  3. 最后,最好和明智的决定是应用工厂模式。见function createType(name) { var types = { "Square": Square, "Circle": Circle, "Triangle": Tringle }; return types.hasOwnProperty(name) ? new types[name]() : null; } 。你也可以找到很好的描述和例子@scniro answer

2
投票

经过仔细考虑,Node.js有一个非常简单的方法。当你以最简单的方式实例化一个对象时,你实际上写了here,其中new <variableName>是一些函数或类的主体,在某个模块中定义和导出。要将此函数/类分配给变量,您需要variableName

所以,而不是

require()

你需要写:

const type = 'Square';
const aSquare = new type();

一个小的缺点是,eslint抱怨(在某些规则设置中)const type = 'Square'; const shape = require(`${pathToShapeModules}/${type}.js`); const aShape = new shape(); s将被放置在模块的顶部。当然,它需要通过尝试...捕获等进行适当的异常处理。所以可能工厂解决方案更好(所以我将接受它)但我认为对于小型专业案例,这个解决方案是可以的。

© www.soinside.com 2019 - 2024. All rights reserved.