javascript - 有条件地扩展当前类
问题描述
我想要一个 JavaScript 类,它可以有条件地从单独的文件中将其他方法添加到自身中。这个想法是将应用程序的不同关注点分离到更易于管理的独立模块中,这些模块仍然可以与母应用程序类中的方法进行交互。因此,单独文件中的附加方法必须能够引用主类中的方法和变量。请参阅下面的代码示例。
我查看了很多不同的解决方案,但它们都有我想要的缺点。
- 我可以
new Uploads()
,但我找不到Uploads.js
方法在主App
类中引用方法的方法 - 我可以使用
extends
,但这不允许有条件扩展 AFAIK - 我可以在原型本身中定义新方法,但这意味着外部文件需要“知道”它将在其中使用的类,这不会使其广泛可重用。
到目前为止,我拥有的最好的是以下内容:
应用程序.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
了一个类。理想情况下(尽管我猜不一定)对于代码可管理性,它们都应该使用相同的语法。
有没有更好/更清洁/更好的方法来做到这一点?
解决方案
与其尝试执行某种疯狂的多重继承,不如尝试拥抱组合?它非常适合解决这类问题。
class App {
constructor(modules) {
if (modules.uploads) {
this.uploads = modules.uploads(this);
}
}
foo() {
console.log('foo!');
}
}
class Uploads {
constructor(context) {
this.context = context;
}
method() {
this.context.foo();
}
}
const app = new App({ uploads: (ctx) => new Uploads(ctx) });
app.uploads.method();
您可以对此非常感兴趣,并使用构建器来配置具有特定类型模块的应用程序。
根据您预期的复杂性,您可能需要考虑使用event buses
, mediators
, 或commands
将事物与主机本身分离。
推荐阅读
- javascript - Invariant Violation:期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义
- visual-studio - Visual Studio 在第一次运行时查找较旧的程序集版本
- angular - Angular 2+ 4+ 将外部 api 与 Angular 标头连接起来
- html - 表格下的按钮对齐在CSS中不起作用
- python - 在 Python 中按升序合并两个已排序的链表:单链表指针更新问题
- macos - 用于在浏览器中打开文件的 Shell 脚本未按预期工作
- css - 使用物化 css 的图像网格/画廊
- php - Laravel 5.6 - 如何从非关系表中获取发布数据?
- android - 在 logcat 中从 Sqlite android 检索数据
- delphi - TWebRequest 中的标头 HTTP 来源