在运行时创建ES6类定义,并添加到'要使用的列表

create ES6 class definition at runtime and add to 'factory' list to be used

本文关键字:列表 添加 ES6 创建 运行时 定义      更新时间:2023-09-26

下面是我目前使用Webpack编译的实现。

// ** ModelTypeA.js ** //
export class ModelTypeA {
  constructor() {
  }
  //etc, class definition
}

// ** ModelFactory.js ** //
export { ModelTypeA } from './ModelTypeA';
export { ModelTypeB } from './ModelTypeB';

// ** Main.js  ** //
import * as ModelFactory from './ModelFactory.js'
let modelName = "ModelTypeA"; //can be changed to "ModelTypeB"
let myModel = new ModelFactory[modelName];

是否有一种方法来创建另一个类,例如ModelTypeC.js与它的定义在运行时(让我们说我有一个文本编辑器在网页上编写和保存),附加到ModelFactory.js,并在Main.js中使用它?

让我们撇开这样一个事实:允许用户在网站的文本编辑器中编写JS代码通常是一个坏主意。

你将无法做你所描述的,因为ES6模块不允许运行时更改import/export语句。这篇文章有一个不错的概述,关键引用:

基本思想是:ES6模块应该是静态可分析的(运行时不能改变导出/导入),所以它不能是动态的。

在这种情况下,您可以做的是以某种不涉及import/export的方式向工厂注册类:

class ModelFactory {
    constructor() {
        this._classes = {}
    }
    register(key, cls) {
        this._classes[key] = cls
    }
    create(key, ...args) {
        return new this._classes[key](...args);
    }
}
// Export a singleton
export default new ModelFactory();
// Register in some other file
import { ModelTypeA } from './ModelTypeA';
import { ModelTypeB } from './ModelTypeB';
import ModelFactory from './ModelFactory';
ModelFactory.register('ModelTypeA', ModelTypeA);
ModelFactory.register('ModelTypeB', ModelTypeB);

现在您可以引入一些用户编写的类并注册它们:

const className = userProvidedData.className;
// Again, don't really do this, it's usually a Bad Idea
const cls = eval(userProvidedData.source);
ModelFactory.register(className, cls);

在运行时定义类(大多数情况下)是一个坏主意。这很容易出现RunTimeException.

如果这些模型类有一些共同的东西,最好有一个泛型类,并根据它所拥有的属性改变实例的行为。