javascript - 无法移动使用 super 的方法
问题描述
我正在读这本书。检查部分“15.6.4.2 陷阱:使用 super 的方法无法移动”
它说明了以下内容
你不能移动使用 super 的方法:这样的方法有一个内部槽 [[HomeObject]] 将它绑定到创建它的对象。如果你通过赋值移动它,它将继续引用超属性的原始对象。
所以,我尝试用不同的对象调用它,也将实例方法分配给不同的对象,但它似乎不起作用。它指的是新对象的属性。大概,作者的意思我没听懂。那么,有人可以举个例子吗?
Hers 是一个小演示,代码如下
class A {
get a() {
return 1;
}
sayHi() {
console.log(this.a)
}
}
class B extends A {
sayHi() {
super.sayHi();
};
}
var obj = {
a: 4
};
let b = new B();
b.sayHi();
// logs 1
b.sayHi.call(obj);
// logs 4
obj.sayHi = b.sayHi;
obj.sayHi();
// logs 4
解决方案
您的代码没问题,因为this
在您移动方法时有效,但super
无效(并且您的代码仅真正测试this
)。以下代码测试super
:
class Bird {
getName() {
return 'Bird';
}
}
class Mammal {
getName() {
return 'Mammal';
}
}
class Human extends Mammal {
getName() {
return super.getName();
}
}
class Duck extends Bird {
}
// Moving method .getName() from Human.prototype to Duck.prototype
Duck.prototype.getName = Human.prototype.getName;
console.log(new Duck().getName()); // 'Mammal' (not 'Bird')
要了解结果,您需要了解其super
工作原理——它使用存储在方法本身中的内部属性[[HomeObject]]
,它不依赖于this
. 也就是说,Human.prototype.getName()
内部工作如下:
Human.prototype.getName = Object.assign(
function me() {
return me.__HomeObject__.__proto__.getName();
},
{ __HomeObject__: Human.prototype }
);
书中解释了更多细节:
推荐阅读
- node.js - 未在承诺链中处理错误
- bash - .jupyter 不能被删除或写入
- sql - 根据 SQL 中多列中的条件创建具有 3 个类别的状态列
- ncurses - ncurses set_field_buffer 和一个两字节的 UTF-8 字符
- http - 使用 http.FileServer 处理自定义 404 页面
- android - 来自多个引用的 Firestore 连接数据
- python - 如何在 conda 中限制包版本?
- r - 在函数内部使用 `expr()`
- ios - 在 UIView 中动画图像
- javascript - Array.map 使用箭头函数在 redux reducer 中返回 null