jus*_*vac 8 javascript inheritance babel typescript ecmascript-6
Javascript的super关键字,当我在Chrome,Babel,TypeScript上运行代码时,我得到了不同的结果.
我的问题是哪个结果是正确的?规范的哪一部分定义了这种行为?
以下代码:
class Point {
getX() {
console.log(this.x); // C
}
}
class ColorPoint extends Point {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(this.x) // A
console.log(super.x) // B
}
m() {
this.getX()
}
}
const cp = new ColorPoint();
cp.m();
Run Code Online (Sandbox Code Playgroud)
结果:
链接:
Chrome是正确的.这是由get和set之间的不平衡引起的.
OrdinarySet是reciever敏感的,但普通的Get不是.
所以super.x = 3具有相同的效果this.x = 3,因为这里的接收器是this.super.x从未达到过的评估this总会得到,undefined因为A.prototype没有这样的领域.
这super.x是一个SuperReference.并且赋值SuperReference将调用PutValue(V,W),然后调用super对象的内部插槽[[Set]],最后调用OrdinarySet.
在纯JavaScript中,该语句super.x = 3基本上等同于:
OrdinarySet(proto, 'x', 3, this).
proto超级对象在哪里,在[[HomeObject]]构造函数内部ColorPoint.proto相当于Object.create(Point.prototype)作为ClassDefinitionEvaluation指定,并且它被传递给作为构造[[HomeObject]].
现在让我们看看它是如何OrdinarySet运作的. 在步骤4c和4d中,规范要求在接收器this而不是proto对象上完成设置操作.
让existingDescriptor成为?[GetOwnProperty]接收机.
如果未定义existingDescriptor,那么
如果IsAccessorDescriptor(existingDescriptor)为true,则返回false.
如果existingDescriptor.[[Writable]]为false,则返回false.
设valueDesc为PropertyDescriptor {[[Value]]:V}.
回来?Receiver.[[DefineOwnProperty]](P,valueDesc).
这些陈述表示OrdinarySet(proto, 3, this)手段this.x = 3.
另一方面,OrdinaryGet 忽略 Receiver.super.x是
OrdinaryGet(proto, 'x', this).
OrdinaryGetReceiver在其条款中根本没有!所以super.x相当于Object.create(Point.prototype).x,undefined当然.
根据经验,如果转换器和浏览器之间存在差异,浏览器(尤其是Chrome)通常对ECMAScript规范更加忠诚.对于运行时效率,Transpilers通常会交换一些边缘情况正确性.
| 归档时间: |
|
| 查看次数: |
497 次 |
| 最近记录: |