javascript - 访问由 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 我确实知道我可以使用组合,但我想了解错误的来源。
解决方案
为什么会发生错误?
因为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)
)。
推荐阅读
- android - 每当我倾斜屏幕时,如何防止按钮和文本视图重叠?
- c# - 如何使用 C# 从字符串中删除序列中的重复\相同字符?
- ios - 从 iPhone 和 iPad 获取用户位置时如何获取 HDOP、PDOP、卫星可用性?
- pandas - 如何使用过滤器提取列
- java - java.lang.Error:未解决的编译问题:sun.misc.BASE64Decoder 无法解析为类型
- sql-server - 从现有 SQL Server 表中删除所有列
- ruby-on-rails - Heroku Ruby Application Error(Missing helper file helpers?)
- reactjs - 如何使我的 JWT 令牌浏览器特定于防止被盗令牌的访问?
- ansible - 与主机的共享连接在以非特权用户身份运行 Ansible 剧本时关闭?
- php - 为邮件正文 PHP 输入新行