ES6等.有可能定义一个包罗万象的方法吗? [英] ES6 et al. is it possible to define a catch-all method?

查看:98
本文介绍了ES6等.有可能定义一个包罗万象的方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当要从子级到父级的方法调用级联时,组合是继承的一种有用替代方法,请参见子扩展类方法调用其父版本,仍然只能看到子数据

Composition is a useful alternative to inheritance when one wants to cascade method calls from child to parent, see child extended class method calls its super version but that still only sees child data

但是,为使子级提供与父级类型兼容的接口,必须实现大量可能具有相同形式的存根方法,即它们只是将调用中继到前一个父级(现在为父级)一个组件).

However, for the child to present an interface that is compatible with parent type, one must implement a potentially large number of stub methods that all have the same form, namely they just relay the call to the former parent (which is now a component).

我的问题在这里,有可能编写一个包罗万象的方法吗?当没有其他方法被调用时,将调用全部捕获方法.包罗万象的只是将调用中继到父组件.因此,存根仅需写入一次.变体可以用于对多个继承进行排序等.

My question here, is it possible to write a catch-all method? A catch-all method would be called when none of the other methods are called. The catch-all would then just relay calls to the parent component. Thus the stub would only have to be written once. Variations could be used to sort multiple inheritance, etc.

类似这样的东西:

  class A {
      constructor(){
        this.x = "super x!";
      }
      f(){
        console.log("I am a super f()!");
      }
      logx(){
        this.f();
        console.log(this.x);
      }
    }

    class B {
      constructor(){
        this.a = new A();
        this.x = "derived x.";
      }
      f(){
        console.log("I am a derived f()");
      }
      logx(){
        this.a.logx();
      }
    }

    let b = new B;
    b.logx();

  I am a super f()!
    super x!

假设性地,它将是这样的:

Hypothetically would instead be something like this:

 class A {
      constructor(){
        this.x = "super x!";
      }
      f(){
        console.log("I am a super f()!");
      }
      logx(){
        this.f();
        console.log(this.x);
      }
    }

    class B {
      constructor(){
        this.a = new A();
        this.x = "derived x.";
      }
      f(){
        console.log("I am a derived f()");
      }
      catch_all(method_name, ...args){
        this.a.method_name(...args);
      }
    }

    let b = new B;
    b.logx();

  I am a super f()!
    super x!

推荐答案

这基于isepa的建议,即使用Fred Truter的函数列出方法.这是一个很好的概念,但并不能使我们达到目标.它需要进行测试,以免破坏现有的方法.同样,仅复制方法也是有问题的,因为父级this.variables将不存在或在子级中具有别名-请注意,这是一种组合,因此它们不打算被继承.无需复制,而是将其转换为呼叫.

This builds on isepa's suggestion to use Fred Truter's function for listing methods. That is a nice concept, but it doesn't quite get us there. It needs a test so as not to clobber existing methods. Also just copying the methods is problematic because the parent this.variables won't be there or will alias in the child - note this is composition so they weren't intended to be inherited. Instead of copying, this turns it into a call.

    //Fred Truter's function:
    Object.methods = function (klass) {
      const properties = Object.getOwnPropertyNames(klass.prototype)
      properties.push(...Object.getOwnPropertySymbols(klass.prototype))
      return properties.filter(name => {
        const descriptor = Object.getOwnPropertyDescriptor(klass.prototype, name)
        if (!descriptor) return false
        return 'function' == typeof descriptor.value && name != 'constructor'
      })
    }

   Object.compose = function (obj0, obj1, ...constructor_args) {
    obj0[obj1.name] = new obj1(...constructor_args);
    Object.methods(obj1).forEach(
      method => {
        if(!obj0[method]) obj0[method] = (...args) => obj0[obj1.name][method](...args);
      }
    );
  }


    // shows using the composition operator:
    class A {
      constructor(){
        this.x = "super x!";
      }
      f(){
        console.log("I am a super f()!");
        console.log(this.x);
      }
      logx(){
        console.log(this.x);
        this.f();
      }
    }

    class B {
      constructor(){
        Object.compose(this, A);
        this.x = "derived x.";
      }
      // f(){ console.log("I am a derived f()"); }
      logx(){
        console.log(this.x);
        this.f();
      }
    }

    let b = new B;
    b.logx();
    b.f();

和预期的输出:

derived x.
I am a super f()!
super x!
I am a super f()!
super x!

然后从f的子版本中删除注释,我们得到的结果是:

Then upon removing the comment from the child version of f, we get, as expected:

derived x.
I am a derived f()

这篇关于ES6等.有可能定义一个包罗万象的方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆