【发布时间】:2020-09-04 23:28:31
【问题描述】:
我想要一个 JavaScript 类,它可以有条件地从单独的文件中将其他方法添加到自身中。这个想法是将应用程序的不同关注点分成更易于管理的独立模块,这些模块仍然可以与母应用程序类中的方法进行交互。因此,单独文件中的附加方法必须能够引用主类中的方法和变量。请参阅下面的代码示例。
我查看了很多不同的解决方案,但它们都有我想要的缺点。
- 我可以做
new Uploads(),但我找不到Uploads.js中的方法引用主App类中的方法的方法 - 我可以使用
extends,但这不允许有条件扩展 AFAIK - I could just define new methods into the prototype itself,但这意味着外部文件需要“知道”它将被使用的类,这不会使其可广泛重复使用。
目前为止我最好的如下:
app.js
const Uploads = require("./Uploads.js");
const config = { hasUploads: true }; // Probably loaded from a file
class App {
constructor() {
/* Only include the separate module if the config says so */
if(config.hasUploads) {
Object.assign(this, Uploads);
}
}
foo() {
/* Something */
}
}
上传.js
module.exports = {
bar() {
this.foo();
}
};
有效,但不知道这是不是最好的解决方案;
- 没有构造函数,所以如果
Uploads.js需要做一些设置,app.js需要包含这样做的逻辑(或者至少知道调用一些唯一命名的假构造函数方法),这似乎并不理想. - 如果
Uploads.js包含与app.js或任何其他可能正在加载的模块同名的方法,它们将被覆盖,从而导致意外行为。 -
Uploads.js是函数对象,而app.js定义一个类。 理想情况下(虽然我猜不一定)为了代码可管理性,它们都应该使用相同的语法。
有没有更好/更清洁/更好的方法来做到这一点?
【问题讨论】:
-
这有点违反了许多面向对象的原则,但我会让 OO 学者对此表示赞同。实际上,我通常会使用虚拟或抽象的 Uploads 实现(什么都不做)来定义基类,然后您可以从该类派生并在派生类中提供该方法的新实现,或者您可以有条件地替换现有的在任何给定实例上实现。
-
在多个文件中拆分一个巨大的
class是行不通的。正如你自己所说,你想要 self-contained 模块。 -
"我可以做
new Uploads(),但我找不到Uploads.js中的方法引用主App类中的方法的方法" - 通过App实例作为上传构造函数的参数:this.uploads = new Uploads(this);(在App的constructor内)。 -
我可以完全接受我的方法可能不是应该做的......但我确实认为想要将一个巨大的类拆分成更小的更易于管理的文件的根本问题在于本身就是一个有效的问题。如果我理解正确,从虚拟类派生也意味着最终“完整”类最终将是 Uploads,而不是 App,对吗?最终应用需要调用的任何类都会根据配置而改变?
-
使用 JS“原型”。请参阅几个先前回答的问题,例如stackoverflow.com/questions/13521833/…
标签: javascript node.js ecmascript-6 es6-class