ES6构造器内给super赋值为何指向类实例?super.x为何为undefined?
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();
问题解答
1. 为何在类的构造函数内给super赋值,实际是给类的实例赋值?
在ES6的类继承机制里,super作为对象使用时本质是个语法糖:读取super的属性时,会去父类的原型对象上查找;但赋值操作会直接指向子类的实例(也就是this)。
这是因为子类继承父类时,最终生成的实例是子类的实例,父类构造函数只是通过super()完成了这个实例的部分初始化。ES6这么规定是为了保证实例的一致性——对super的赋值不会去修改父类的原型或父类实例,而是直接作用于当前子类的实例对象。
2. 为何示例中super.x输出undefined,this.x输出3?
- 关于
super.x的读取:super.x属于属性读取操作,会去父类A的原型对象(A.prototype)上查找x。但在A的构造函数里,x是挂载在this(父类实例)上的实例属性,并没有放到A.prototype中,所以父类原型里根本不存在x这个属性,自然返回undefined。 - 关于
super.x = 3和this.x:这个赋值操作按照规则,实际是给子类实例的this.x赋值。之前this.x已经被设为2,现在又被覆盖成3,所以最后console.log(this.x)输出3。
内容的提问来源于stack exchange,提问作者simba
相关产品推荐
相关产品推荐

