ES6等。 是否有可能定义一个包罗万象的方法是什么?(ES6 et al. is it poss

2019-10-29 12:12发布

组合物是有用的替代,当一个人想从孩子级联方法调用父,见继承子扩展分类方法调用其超强版,但仍然只能看到孩子的数据

然而,为孩子呈现一个接口,与父类型兼容,必须实现一个潜在的大量的存根方法,所有具有相同的形式,即他们只是中继呼叫前母公司(也就是现在的一个组件) 。

在这里我的问题,是有可能写出一个包罗万象的方法是什么? 没有其他方法被调用时,一个包罗万象的方法将被调用。 然后,将捕获所有只会传递给父组件调用。 因此,短线将只需要写入一次。 变化可以用来排序多重继承,等等。

事情是这样的:

  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!

可以想像反而会是这样的:

 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!

Answer 1:

使用弗雷德Truter的功能拉从一个类的方法通过ES6类的方法和属性迭代 :

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'
    })
}

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

class B {
    constructor() {
        this.a = new A();
        this.x = "derived x. ";
        Object.methods(A).forEach(method => this[method] = this.a[method]);
    }
    logx() {
        console.log(this.x + "log")
    }
}

let b = new B;
b.f(); //"I am a super f()!"
b.logx(); //"derived x. log"


Answer 2:

这种建立在isepa的建议,使用弗雷德Truter的功能列表的方法。 这是一个很好的概念,但它并没有完全得到我们那里。 它需要一个测试,以便不揍现有的方法。 也仅仅复制方法是有问题的,因为父this.variables不会在那里或将别名孩子 - 注意,这是组成所以他们不打算继承。 而不是复制的,这把它变成一个电话。

    //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的子版本删除注释,我们得到的,符合市场预期:

derived x.
I am a derived f()


文章来源: ES6 et al. is it possible to define a catch-all method?