JavaScript-动态加载类并使用特定属性创建新实例



我有一个node.js v11.11.0应用。在此应用中,我的文件的结构如下:

./src
  /animals/
    animal.js
    tiger.js
    koala.js
  index.js

如上所示,我在animals目录中定义了三个类。随着时间的流逝,我打算添加具有更复杂逻辑的其他动物。目前,我的课程定义为:

Animal.js

'use strict';
class Animal {
  constructor(properties) {
    properties = properties || {};
    this.kind = 'Unknown';
  }
  eat(foods) {
    for (let i=0; i<foods.length; i++) {
      console.log(`Eating ${foods[i]}`);
    }
  }
}
module.exports = Animal;

Tiger.js

'use strict';
const Animal = require('./animal');
class Tiger extends Animal {
  constructor(properties) {
    super(properties);
    this.kind = 'Tiger';
  }
  eat(foods) {
    for (let i=0; i<foods.length; i++) {
      if (foods[i].kind === 'meat') {
        console.log(`Eating ${foods[i]}`);
      }
    }
  }
}
module.exports = Tiger;

koala.js

'use strict';
const Animal = require('./animal');
class Koala extends Animal {
  constructor(properties) {
    super(properties);
    this.kind = 'Koala';
  }
  eat(foods) {
    for (let i=0; i<foods.length; i++) {
      if (foods[i].kind === 'plant') {
        console.log(`Eating ${foods[i]}`);
      }
    }
  }
}
module.exports = Koala;

我正在尝试根据用户输入的内容动态创建其中一个类的实例。例如,我正在这样做:

index.js

const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
})
readline.question('What animal file do you want to load?', (fname) => {
  let properties = {
    name: 'My Pet'
  };
  let Animal = require(fname);
  let pet = Object.create(Animal.prototype, properties);
});

如果我运行此并输入./animals/tiger.js,我会遇到错误。错误说:Property description must be an object。我不明白。TigerKoala都扩展了Animal。同时,由于我的列表将是动态的,因此我需要免费的表单选项来键入文件路径并动态加载类。因此,我无法使用此处显示的方法,该方法专门列出了类名称。

如何动态加载一个类并使用特定属性创建该类的实例?

Object.create的第二个参数与您要传递给 Object.defineProperties的参数相同,因此您的 properties是无效的。而是使用object.Assign:

 Object.assign(Object.create(Animal.prototype), properties)

但是为什么不叫构造函数?

 new Animal(properties)

其次:

 properties = properties || {};

可能是:

 this.properties = properties || {};

我不建议动态require,尤其是从用户输入的值中,而是创建一个查找对象:

 const AnimalByName = {
   Bear: require("./Bear"),
   //...
 };
 const instance = new AnimalByName[name](properties);

最新更新