当要从子级到父级的方法调用级联时,组合是继承的一种有用替代方法,请参见child extended class method calls its super version but that still only sees child data
但是,为了让孩子展示与父类型兼容的接口,必须实现大量可能具有相同格式的存根方法,即它们只是将调用中继到前一个父对象(现在是一个组件)。
我的问题在这里,有可能编写一个包罗万象的方法吗?当没有其他方法被调用时,将调用全部捕获方法。然后,全部捕获只是将调用中继到父组件。因此,存根仅需写入一次。变体可以用于对多个继承进行排序等。
类似这样的东西:
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!
答案 0 :(得分:0)
使用Fred Truter的函数从类Iterate through methods and properties of an ES6 class中提取方法:
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"
答案 1 :(得分:0)
这是基于isepa的建议,即使用Fred 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()