访问 Object.create 创建的对象中的父(超级)方法
Access parent (super) method in object created by 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
我这样做的方式正确吗?
为什么会出现错误?
更新:P.S。我知道我可以使用组合,但我想了解错误的来源。
您想使用 extends
关键字,例如:
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
Why does the error happen?
因为使用super
的W.prototype.f
方法只关心W.prototype
的原型来评估super
将引用什么。 super
关键字本质上是一个静态查找,依赖于声明该方法的对象,忽略调用该方法的对象的原型链。
如果我们translate到
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
不是一个函数…
所以您可以通过 Object.setPrototypeOf(W.prototype, C.prototype)
而不是 Object.setPrototypeOf(w, c)
(或 w = Object.create(c, …)
)来解决问题,但我不推荐这样做。如果你真的想影响所有实例,你已经写了 class W extends C
(这与使用 Object.setPrototypeOf(W.prototype, C.prototype)
的结果相同)。
我想创建一个包装器机制:我们包装 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
我这样做的方式正确吗?
为什么会出现错误?
更新:P.S。我知道我可以使用组合,但我想了解错误的来源。
您想使用 extends
关键字,例如:
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
Why does the error happen?
因为使用super
的W.prototype.f
方法只关心W.prototype
的原型来评估super
将引用什么。 super
关键字本质上是一个静态查找,依赖于声明该方法的对象,忽略调用该方法的对象的原型链。
如果我们translate到
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
不是一个函数…
所以您可以通过 Object.setPrototypeOf(W.prototype, C.prototype)
而不是 Object.setPrototypeOf(w, c)
(或 w = Object.create(c, …)
)来解决问题,但我不推荐这样做。如果你真的想影响所有实例,你已经写了 class W extends C
(这与使用 Object.setPrototypeOf(W.prototype, C.prototype)
的结果相同)。