JavaScript中无法使用super.member.Func()?如何正确改写?
关于JavaScript中super的使用误区与正确写法
问题背景
先看一个super的典型误区:
class Base { baseField = 10; } class Extended extends Base { extendedField = super.baseField; // 结果为undefined }
我自己的代码遇到了类似问题:
class Parent{ ext_class; constructor(ext){ this.ext_class=ext; } } class Child extends Parent{ constructor(ext){ super(ext); } Method(p){ super.ext_class.ExecFunc(p); // 无法调用该方法 } }
我没法通过super调用父类实例成员对象的方法,虽然可以在子类里保存这个对象,但不确定这么做是否合理,想知道正确写法。
另外我做了两组测试:
测试代码1(不符合预期)
class Base { constructor(bf){ this.baseField = bf } } Base.prototype.baseField = 1; class Extended extends Base { constructor(bf){ super(bf) } extendedField = super.baseField; } console.log(new Extended(12).extendedField); // 输出1,而非预期的12
测试代码2(符合预期)
class Base { constructor(bf){ Base.prototype.baseField = bf } } class Extended extends Base { constructor(bf){ super(bf) } extendedField = super.baseField; } console.log(new Extended(13).extendedField); // 输出13
原因分析与正确写法
核心问题在于:super指向的是父类的原型对象,而非父类的实例。
- 实例属性(比如
this.baseField、this.ext_class)是挂载在实例本身的,不在原型链上,所以用super.xxx访问不到这些实例属性,只能访问父类原型上的属性/方法。 - 测试代码1里,
super.baseField取到的是Base.prototype.baseField的值1,而非实例的this.baseField的12;测试代码2里直接修改了原型上的baseField,所以super.baseField能拿到修改后的值。
针对你的代码的正确写法
不需要用super,直接用this访问实例属性即可——子类实例继承了父类的实例属性,this.ext_class就是父类构造函数里赋值的那个对象:
class Parent{ ext_class; constructor(ext){ this.ext_class = ext; } } class Child extends Parent{ constructor(ext){ super(ext); } Method(p){ this.ext_class.ExecFunc(p); // 直接用this访问实例属性 } }
补充说明
如果确实需要访问父类原型上的成员,才用super。比如父类在原型上定义了方法:
class Parent { prototypeMethod() { console.log('父类原型方法'); } } class Child extends Parent { prototypeMethod() { super.prototypeMethod(); // 调用父类原型方法 console.log('子类原型方法'); } }
内容的提问来源于stack exchange,提问作者Dmitry Kovalevsky
相关产品推荐
相关产品推荐

