Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有条件地扩展当前类_Javascript_Node.js_Ecmascript 6_Es6 Class - Fatal编程技术网

Javascript 有条件地扩展当前类

Javascript 有条件地扩展当前类,javascript,node.js,ecmascript-6,es6-class,Javascript,Node.js,Ecmascript 6,Es6 Class,我想要一个JavaScript类,它可以有条件地从单独的文件向自身添加其他方法。其想法是将应用程序的不同关注点分离为更易于管理的自包含模块,这些模块仍然可以与母应用程序类中的方法交互。因此,单独文件中的其他方法必须能够引用主类中的方法和变量。请参阅下面的代码示例 我看了很多不同的解决方案,但它们都有我想要的缺点 我可以执行new Uploads(),但是我找不到一种方法让Uploads.js中的方法引用mainApp类中的方法 我可以使用扩展,但这不允许有条件扩展AFAIK ,但这意味着外部文

我想要一个JavaScript类,它可以有条件地从单独的文件向自身添加其他方法。其想法是将应用程序的不同关注点分离为更易于管理的自包含模块,这些模块仍然可以与母应用程序类中的方法交互。因此,单独文件中的其他方法必须能够引用主类中的方法和变量。请参阅下面的代码示例

我看了很多不同的解决方案,但它们都有我想要的缺点

  • 我可以执行
    new Uploads()
    ,但是我找不到一种方法让
    Uploads.js
    中的方法引用main
    App
    类中的方法
  • 我可以使用
    扩展
    ,但这不允许有条件扩展AFAIK
  • ,但这意味着外部文件需要“知道”它将要在其中使用的类,这并不能使其广泛可重用
到目前为止,我所掌握的最好信息如下:

app.js 上传.js 这是可行的,但我不知道这是否是最好的解决方案

  • 没有构造函数,因此如果
    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();