类中super.prop的指向由何决定?关于super绑定逻辑的疑问
关于类中super绑定逻辑的解惑
首先得掰明白一个关键区别:类初始化阶段只是把方法“放”到原型上,并不会执行方法里的代码。方法里的super到底指向哪,是在方法被调用的那一刻才确定的,不是定义的时候。
举个具体的例子:
class Parent { static x = '静态x'; x = '原型x'; } class Child extends Parent { // 静态属性:类初始化阶段执行,super指向Parent本身 static y = super.x; // 实例字段:实例创建阶段执行,super指向Parent.prototype z = super.x; // 原型方法:类初始化阶段只是把这个函数挂到Child.prototype上,不执行内部代码 method() { console.log(super.x); // 这行代码要等method被调用时才执行 } } // 类初始化阶段已经完成,此时Child.y是'静态x' console.log(Child.y); // 创建实例时执行z的赋值,此时super指向Parent.prototype,所以实例的z是'原型x' const child = new Child(); console.log(child.z); // 调用method时,执行上下文是实例child,此时super绑定到Parent.prototype,输出'原型x' child.method();
为什么要这么设计?其实是为了贴合方法的调用场景:
- 原型方法是给实例用的,调用时上下文是实例,自然要让super指向父类的原型,这样才能访问父类的实例属性和方法;
- 静态方法是给类本身用的,调用时上下文是类,所以super指向父类本身,对应访问父类的静态属性和方法。
MDN说的“执行上下文是实例创建还是类初始化”,针对的是那些在初始化阶段就执行的代码(比如静态字段、实例字段的赋值语句),而方法里的代码属于“调用时执行”,它的执行上下文是调用时的场景(实例调用就是实例上下文,类调用就是类上下文)。
内容的提问来源于stack exchange,提问作者kmack
相关产品推荐
相关产品推荐

