首页 > 解决方案 > 访问由 Object.create 创建的对象中的父(超级)方法

问题描述

我想创建一个包装机制:我们包装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

我是否以正确的方式执行此操作?

为什么会发生错误?

更新: PS 我确实知道我可以使用组合,但我想了解错误的来源。

标签: javascriptoopinheritanceecmascript-6super

解决方案


为什么会发生错误?

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

如果我们翻译

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

我们可以看到这Object.prototype.f不是一个函数……</p>


所以你可以通过Object.setPrototypeOf(W.prototype, C.prototype)代替Object.setPrototypeOf(w, c)(或w = Object.create(c, …))来解决这个问题,但我不建议这样做。如果您真的想影响所有实例,那么您已经编写好class W extends C了(与 using 的结果相同Object.setPrototypeOf(W.prototype, C.prototype))。


推荐阅读