Javascript 有条件地扩展当前类
我想要一个JavaScript类,它可以有条件地从单独的文件向自身添加其他方法。其想法是将应用程序的不同关注点分离为更易于管理的自包含模块,这些模块仍然可以与母应用程序类中的方法交互。因此,单独文件中的其他方法必须能够引用主类中的方法和变量。请参阅下面的代码示例 我看了很多不同的解决方案,但它们都有我想要的缺点Javascript 有条件地扩展当前类,javascript,node.js,ecmascript-6,es6-class,Javascript,Node.js,Ecmascript 6,Es6 Class,我想要一个JavaScript类,它可以有条件地从单独的文件向自身添加其他方法。其想法是将应用程序的不同关注点分离为更易于管理的自包含模块,这些模块仍然可以与母应用程序类中的方法交互。因此,单独文件中的其他方法必须能够引用主类中的方法和变量。请参阅下面的代码示例 我看了很多不同的解决方案,但它们都有我想要的缺点 我可以执行new Uploads(),但是我找不到一种方法让Uploads.js中的方法引用mainApp类中的方法 我可以使用扩展,但这不允许有条件扩展AFAIK ,但这意味着外部文
- 我可以执行
,但是我找不到一种方法让new Uploads()
中的方法引用mainUploads.js
类中的方法App
- 我可以使用
,但这不允许有条件扩展AFAIK扩展
- ,但这意味着外部文件需要“知道”它将要在其中使用的类,这并不能使其广泛可重用
- 没有构造函数,因此如果
需要进行一些设置,Uploads.js
需要包含这样做的逻辑(或者至少知道调用一些唯一命名的伪构造函数方法),这似乎并不理想app.js
- 如果
包含与Uploads.js
同名的方法或任何其他可能加载的模块,它们将被覆盖,导致意外行为app.js
是函数的对象,而Uploads.js
定义了一个类。理想情况下(虽然我猜不一定)对于代码的可管理性,它们应该使用相同的语法app.js
有更好/更干净/更好的方法吗?修复从上载文件覆盖现有方法的一个选项是在循环中分配新方法并检查重复的方法(
对象。在这种情况下分配不理想)并且只添加一次更新:
const上传={
bar(){
这是一家名为.foo的公司(“从酒吧取名”);
}
};
const config={hasUploads:true,//可能是从文件加载的
配置:false
};
类应用程序{
构造函数(){
/*如果配置中有说明,则仅包括单独的模块*/
if(config.hasUploads&&!config.configured){
const proto=this.constructor.prototype;
const methods=Object.keys(上传);
methods.forEach(name=>{
if(proto[名称]){
抛出新错误(“应用程序已经有方法”+名称);
}
proto[name]=上传[name];
});
config.configured=true;
}
}
foo(arg){
/*某物*/
控制台日志(arg);
}
}
const app=新app();
app.bar()
修复从上载文件覆盖现有方法的一个选项是在循环中分配新方法并检查重复的方法(对象。在这种情况下分配不理想),并且只添加一次更新:
const上传={
bar(){
这是一家名为.foo的公司(“从酒吧取名”);
}
};
const config={hasUploads:true,//可能是从文件加载的
配置:false
};
类应用程序{
构造函数(){
/*如果配置中有说明,则仅包括单独的模块*/
if(config.hasUploads&&!config.configured){
const proto=this.constructor.prototype;
const methods=Object.keys(上传);
methods.forEach(name=>{
if(proto[名称]){
抛出新错误(“应用程序已经有方法”+名称);
}
proto[name]=上传[name];
});
config.configured=true;
}
}
foo(arg){
/*某物*/
控制台日志(arg);
}
}
const app=新app();
app.bar()代码>与其尝试执行某种疯狂的多重继承,为什么不尝试采用组合呢?这对解决这类问题很有好处
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();
您可以使用此功能,并使用构建器配置具有特定模块类型的应用程序
根据您预期的复杂性,您可能希望考虑使用事件总线
、中介
、或命令
将事物与主机本身分离。与其尝试执行某种疯狂的多重继承,不如尝试采用组合方式?这对解决这类问题很有好处
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();
您可以使用此功能,并使用构建器配置具有特定模块类型的应用程序
根据您预期的复杂性,您可能希望考虑使用事件总线
、中介
、或命令
将事物与主机本身解耦。这有点违反了许多面向对象原则,但我会让面向对象学者插话。实际上,我通常会用一个虚拟或抽象的上传实现(什么都不做)来定义基类然后,您可以从该类派生并在派生类中提供该方法的新实现,也可以有条件地替换任何给定实例上的现有实现。在多个文件中拆分一个巨大的类是行不通的。正如你自己所说的,你想要的是自包含的模块。“我可以做new Uploads()
,但是我找不到方法让Uploads.js
中的方法引用主App
类中的方法”-将App
实例作为参数传递给Uploads构造函数:this.Uploads=new Uploads(this)代码>(在应用程序的构造函数中)。我完全可以接受,我的方法可能不是应该做的。。。但我认为潜在的问题
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();