问题描述
在看阮一峰大神的ECMAScript 6入门中有关继承的部分的时候,有一个问题:前面提到super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类
那么下面的代码
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();
当设置super.x = 3
时,我的理解相当于是A.prototype.x = 3
但实际上好像这里的super就像this一样,虽然文中提到ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例
,但我认为这里的super不是在调用父类的方法
结果
希望大神能帮我解释一下这里super怎么回事,万分感激
super.x = 3;
这个赋值有点特殊。
super 是 A.prototype 。对它的读取来自
A.prototype
。但是,对它的赋值会进入this
里。 这是向super.x
赋值特殊的地方。读取的时候:
console.log(super.x)
,会从A.prototype
里读,里面没有x
,于是输出undefined
。==================
以下写给想看一眼标准的:
val.x
的形式会生成一个 Reference ,记录了它是哪来的 (base,这里是val
) ,它叫什么 (referenced name,这里是"x"
),以及其它。但是
super.x
会额外记录一个信息,就是当前的this
(thisValue)。super.x
的 base 是父类的 prototype 。赋值的时候,会使用 PutValue(V, W) ,其实 V 就是刚刚提到的
super.x
生成的 Reference,W 是要被赋进去的值。然后它会执行:GetReferencedName(V) 与 GetThisValue(V) 分别取出了 Refrence 里记录的 refrenced name (
"x"
),与 thisValue (保存的this
)。它是给 base 的
"x"
属性赋值 W 。但是多了一个 thisValue 是干嘛的呢 ...我们来看真正执行赋值的地方:OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)
这里 O 是上面的 base (父类的 prototype),P 是属性名 (
"x"
),V 的要赋的值,Receiver 就是 thisValue这个算法略长,拿出其中一步(这一步也不短 ...):
可以看到,所有的值,其实都写进了 Receiver ,也就被保存的
this
。注:对普通的
val.x
,Reference 没有 thisValue, GetThisValue 直接返回 base 。这样OrdinarySetWithOwnDescriptor 中 O 与 Receiver 是同一个对象。注2: 读的时候,如果不是 getter ,直接返回 base 里的属性值。
注3: super.func() 里的
this
,用的 thisValue。val.func()
的this
,用的 base (也就是val
)