es6类里的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();

对两次console出来的结果不理解。
这段代码出自阮一峰的es6

阅读 3.2k
3 个回答

设置 super.x 时,x 属性被设置在 this 上(6.b. [[Set]] 4.d, 5.f),而 this 指向的是正在创建的 b 对象。

访问 super.x 时,依旧是相同的引用,GetValue 调用的了上级类的 [[Get]] 方法,走到了 4.c 就返回了 undefined,并没有 Receiver(this 对象)的什么事。


PS: JavaScript 真是复杂而又奇怪啊。

赋值的时候super相当于子类的this。
取值的时候super是父类的原型。

在子类中,super关键字代表父类实例,即父类的this对象.
子类必须在constructor方法中调用super方法,否则新建实例时会报错,
这是因为子类没有自己的this对象,而是继承了父类的this对象,然后对其加工.
如果不调用super方法,子类就得不到this对象.
super的词法定义应当只有super()和super.xxx()两种用法,是不允许super.x = 3这样赋值的.
this.x应该是输出2的,在子类中this.x = 2,对这个属性重新赋值了.

class A {
    constructor() {
        this.x = 1;
    }
    toString() {
        console.log('父类');
    }
}

class B extends A {
    constructor() {
        super();
        this.x = 2; // 私有的this.x
        super.x = 3;
        console.log(super());   // B{x: 1},super指代父类的实例,即父类的this对象
        super.toString();   // 父类
        console.log(super.x);
        console.log(this.x);
    }
}

let a = new A();
console.log(a.x);   // 1
let b = new B();    // super.x undefined  this.x 2
console.log(b.x);   // 2
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题