javascript:动态创建类实例

时间:2018-04-17 01:14:31

标签: javascript class

我正在编写一个应用程序,其功能可以通过config.json打开和关闭,如下所示:

"appFeatures": {
    "header": {
      "create": true,
      "title": "Here Comes the Sun"
    },
    "imageStrip": {
      "create": false,
      "imageDirectory":  "../data/images",
      "imageDimensions": [288, 162]
    },
    "areaChart": {
      "create": true
    },
    "axes": {
      "create": true
    }
}

对于每个功能,已经存在实现该功能的相同名称的相应类。我想使用该功能的名称来创建该类的新实例。获取config.json后,我的代码(在Main.js类中)看起来像:

this.features = Object.entries(this.config.appFeatures)
  .filter((entry) => {
    return entry[1].create === true;
  });

this.features.forEach((feature) => { this.createFeatureInstances(feature[0]); });

然后我尝试创建实例,la this.header = new Header()

  createFeatureInstances(featureName) {
    const className = `${featureName.replace(featureName[0], featureName[0].toUpperCase())}`;

    this[`${featureName}`] = new Function(`
      return class ${className} {}
    `)();

这会创建一个新的空Header类,我认为是它的实例。它不是我已编写的Header类,并且想要为其创建实例。我如何编写createFeatureInstances函数,以便创建与特征对应的每个类的实例?

编辑由于其他人未来可能会在此应用中添加新功能,因此我希望尽量减少硬编码应用可用功能的时间。使用我目前的设计,另一个开发人员可以通过编写新的要素类,将该类导入Main.js类,并将配置条目弹出到配置.json而不必触及代码中的任何其他内容来添加另一个功能。出于这个原因,像这样的解决方案:Create an instance of a class in ES6 with a dynamic name?不会给我一个解决方案,因为它们依赖于已经存在的类的完整列表。

2 个答案:

答案 0 :(得分:0)

您可以使用以下代码段使用字符串初始化cooresponding(有效和现有)类:

var dynamicClassInstance = new this[classNameString]();

答案 1 :(得分:0)

您需要在某处进行名称类映射。工厂功能或其他地方是您的电话。您当前的解决方案缺少这个,这导致了问题:

  

...创建一个新的空Header类,我想,它是它的实例。它不是我已编写的Header类,并且想要为

创建实例

用一个简单的例子解释一些



// Imagine you've defined Test
class Test {
  callMe() {}
}

// And your consumer wants a className Test to be created
const className = "Test";

// This is a simple map of the name to class
const nameToClass = {
  "Test": Test
}

// This creates a new class called Test, not your defined class
const AttemptedDynamicTest = new Function(`
      return class ${className} {}
    `)();

// The next two logs just prove the previous comment
console.log(Test === AttemptedDynamicTest); // false
console.log(typeof AttemptedDynamicTest.prototype.callMe); // undefined

// What you really need is to maintain a map, and just use it to dynamically
// create a new instance every time
console.log(typeof nameToClass[className].prototype.callMe); // function