如何在不用在ES6中使用super来扩展一个类?

是否可以在不调用方法来调用父类的情况下扩展 ES6 中的类?super

编辑:这个问题可能会产生误导。是我们必须称之为super()的标准,还是我错过了什么?

例如:

class Character {
   constructor(){
      console.log('invoke character');
   }
}

class Hero extends Character{
  constructor(){
      super(); // exception thrown here when not called
      console.log('invoke hero');
  }
}

var hero = new Hero();

当我不调用派生类时,我遇到了一个范围问题 - >super()this is not defined

我正在用 iojs 运行这个 - 在 v2.3.0 中和谐


答案 1

ES2015 (ES6) 类的规则基本上可以归结为:

  1. 在子类构造函数中,在 调用 之前不能使用。thissuper
  2. 如果 ES6 类构造函数是子类,则必须调用,或者它们必须显式返回某个对象以取代未初始化的对象。super

这归结为ES2015规范的两个重要部分。

8.1.1.3.4 节定义了决定函数中内容的逻辑。类的重要部分是它可能处于某个状态,并且当处于此状态时,尝试使用将引发异常。thisthis"uninitialized"this

9.2.2 节 ,它定义了通过 或 称为 的函数的行为。调用基类构造函数时,在 的步骤 #8 初始化,但对于所有其他情况,未初始化。在构造结束时,被调用,因此如果尚未被调用(因此初始化),或者没有返回显式替换对象,则构造函数调用的最后一行将引发异常。[[Construct]]newsuperthis[[Construct]]thisGetThisBindingsuperthis


答案 2

新的 es6 类语法只是带有原型的“旧”es5“类”的另一种表示法。因此,如果不设置特定类的原型(基类),则无法实例化该类。

这就像把奶酪放在三明治上而不做一样。另外,在制作三明治之前,你不能放奶酪,所以...

...在调用超类之前使用关键字也是不允许的。thissuper()

// valid: Add cheese after making the sandwich
class CheeseSandwich extend Sandwich {
    constructor() {
        super();
        this.supplement = "Cheese";
    }
}

// invalid: Add cheese before making sandwich
class CheeseSandwich extend Sandwich {
    constructor() {
        this.supplement = "Cheese";
        super();
    }
}

// invalid: Add cheese without making sandwich
class CheeseSandwich extend Sandwich {
    constructor() {
        this.supplement = "Cheese";
    }
}

如果未为基类指定构造函数,则使用以下定义:

constructor() {}

对于派生类,使用以下默认构造函数:

constructor(...args) {
    super(...args);
}

编辑:在:developer.mozilla.org

When used in a constructor, the super keyword appears alone and must be used before the this keyword can be used.