Javascript 访问由object.create创建的对象中的父(超级)方法

Javascript 访问由object.create创建的对象中的父(超级)方法,javascript,oop,inheritance,ecmascript-6,super,Javascript,Oop,Inheritance,Ecmascript 6,Super,我想创建一个包装机制:我们包装c,这样新的对象w有自己的属性和方法,但是c也可以访问 // Note: this class might be from an external lib class C { f() { console.log('f (original)'); this.p = 'p'; } } class W { f() { console.log('f (new)'); super.f(); // TypeError: (inte

我想创建一个包装机制:我们包装
c
,这样新的对象
w
有自己的属性和方法,但是
c
也可以访问

// Note: this class might be from an external lib
class C {
  f() {
    console.log('f (original)');
    this.p = 'p';
  }
}

class W {
  f() {
    console.log('f (new)');
    super.f();  // TypeError: (intermediate value).f is not a function
    console.log(this.p);
  }
}

// Note: this value is external for us
const c = new C();

const w = Object.create(null, Object.getOwnPropertyDescriptors(W.prototype));
Object.setPrototypeOf(w, c);

w.f();  // expected:
        // f (new)
        // f (original)
        // p
我这样做是否正确

为什么会发生错误


更新:顺便说一句,我知道我可以使用合成,但我想了解错误的来源。

您想使用
扩展
关键字,例如:

    class C {
        f() { console.log( "C.f" ); }
    }

    class W extends C {
        f() {
            super.f()
            console.log( "W.f" );
        }
    }

    const w = new W();
    w.f(); // will output C.f W.f
为什么会发生错误

因为使用
super
W.prototype.f
方法只关心
W.prototype
的原型,以评估
super
将引用的内容。
super
关键字本质上是一个静态查找,取决于声明方法的对象,忽略调用方法的对象的原型链

如果我们愿意

我们可以看到,
Object.prototype.f
不是一个函数



因此,您可以通过执行
Object.setPrototypeOf(W.prototype,C.prototype)
而不是
Object.setPrototypeOf(W,C)
(或
W=Object.create(C,…)
)来解决这个问题,但我不推荐这样做。如果您真的想影响所有实例,您应该已经编写了
类W扩展C
(这将产生与使用
对象相同的结果。setPrototypeOf(W.prototype,C.prototype)
)。

可能是。。。在那里阅读,它可能会解决您的问题。@gugateider谢谢,但很抱歉,我看不到答案。
obj
您想包装什么?您发布的代码中没有
obj
变量。请查看并更新:P.S.我知道我可以使用合成,但我想了解错误的来源。否。对象
c
通过调用外部llibrary函数给出。它的属性在代码中不可访问。我们可以使用构图。但那是另一个故事……啊,我忘了
f
不是
W.f
,而是
W.prototype.f
。。。现在我看到了所有的链条!非常感谢!:)
class W {
  f() {
    console.log('f (new)');
    Object.getPrototypeOf(W.prototype).f.call(this); // TypeError: (intermediate value).f is not a function
    console.log(this.p);
  }
}