当前位置: 首页 > 知识库问答 >
问题:

如何在ES6中扩展类而不必使用super?

权玉泽
2023-03-14

是否可以在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()时,我遇到了一个作用域问题-

我用iojs在v2.3.0中运行这个

共有3个答案

林德辉
2023-03-14

有多个答案和评论指出super必须是构造函数中的第一行。这完全是错误的@loganfsmyth答案包含要求的参考资料,但归结为:

继承(扩展)构造函数必须在使用之前调用超级,即使未使用也必须在返回之前调用

请参阅下面的片段(Chrome...),了解为什么在调用超级之前使用语句(不使用this)是有意义的。

'use strict';
var id = 1;
function idgen() {
  return 'ID:' + id++;
}

class Base {
  constructor(id) {
    this.id = id;
  }

  toString() { return JSON.stringify(this); }
}

class Derived1 extends Base {
  constructor() {
    var anID = idgen() + ':Derived1';
    super(anID);
    this.derivedProp = this.baseProp * 2;
  }
}

alert(new Derived1());

杭英杰
2023-03-14

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

这就像在三明治上放奶酪而不做一样。而且在做三明治之前你不能放奶酪,所以。。。

…也不允许在使用super()调用超类之前使用this关键字。

// 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.

来源

长孙绍辉
2023-03-14

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

  1. 在子类构造函数中,这个不能使用,直到调用了Super
  2. ES6类构造函数必须调用超级,如果他们是子类,或者他们必须显式返回一些对象来代替未初始化的对象。

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

第8.1.1.3.4节定义了决定函数中的内容的逻辑。类的重要部分是,可能处于的“未初始化”状态,当处于该状态时,尝试使用将引发异常。

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

 类似资料:
  • 问题内容: 是否可以在ES6中扩展类而不用调用方法来调用父类? 编辑:这个问题可能会引起误解。 这是我们必须打电话的标准,还是我遗漏了一些东西? 例如: 当我不调用派生类时,我遇到了范围问题-> 我正在v2.3.0中使用iojs –harmony运行它 问题答案: ES2015(ES6)类的规则基本上可以归结为: 在子类构造函数中,只有在被调用之前才能使用。 ES6类构造函数必须是子类,否则必须调

  • 这是我现在面临的问题。我有一个类,假设 ,这个类定义了一个名为 的方法,该方法返回一个 实例。类 在 内部定义,并被声明为。我想做的是定义一个扩展的类,但我也我自己的功能(方法,属性等)来扩展。我也希望返回。 问题是< code>Bar是最终的。下面是我想做的一个例子: 我想做的是: 我怎样才能做到这一点? [编辑]我正在为我的问题添加更多详细信息。我实际上正在为 Jenkins 开发一个插件,搜

  • 问题内容: 我想在Firefox扩展中使用jQuery,我将库导入到xul文件中,如下所示: 但是xul文件中无法识别$()函数,jQuery()也无法识别。 我还尝试过将“ content.document”对象(该对象反映“ document”对象)作为上下文参数传递给jQuery函数,如下所示: 但仍然无法正常工作,以前有人遇到过这个问题吗? 问题答案: 我使用以下内容: 这是一个

  • 我正在尝试做的是创建一个chrome扩展,创建新的,嵌套的,书签文件夹,使用承诺。 执行此操作的函数是chrome.bookmarks.create()。但是我不能只循环这个函数,因为chrome.bookmarks.create是异步的。我需要等待,直到文件夹创建,并获得它的新ID,然后继续它的子级。 承诺似乎是要走的路。不幸的是,我找不到一个使用异步调用和自己的回调(如chrome.bookm

  • 我在React中测试ES6语法,并编写如下组件:

  • 我已经创建了一个数据类 如何正确重写/扩展自定义DataClass的toString方法?