Como estender uma aula sem ter que usar super no ES6?

É possível estender uma class no ES6 sem chamar o método super para chamar a class pai?

EDIT: a questão pode ser enganosa. É o padrão que temos que chamar de super() ou estou faltando alguma coisa?

Por exemplo:

 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(); 

Quando não estou chamando super() na class derivada estou recebendo um problema de escopo -> this is not defined

Estou executando isso com o iojs –harmony in v2.3.0

As regras para as classs ES2015 (ES6) basicamente se resumem a:

  1. Em um construtor de class filho, this não pode ser usado até que o super seja chamado.
  2. Os construtores de class ES6 DEVEM chamar super se forem subclasss, ou devem explicitamente retornar algum object para tomar o lugar daquele que não foi inicializado.

Isso se resume a duas seções importantes da especificação ES2015.

A seção 8.1.1.3.4 define a lógica para decidir o que é this na function. A parte importante para as classs é que é possível que this esteja em um estado "uninitialized" e, quando estiver nesse estado, tentar usar this lançará uma exceção.

Seção 9.2.2 , [[Construct]] , que define o comportamento das funções chamadas via new ou super . Ao chamar um construtor de class base, this é inicializado na etapa nº 8 de [[Construct]] , mas para todos os outros casos, this não é inicializado. No final da construção, GetThisBinding é chamado, portanto, se super ainda não foi chamado (assim inicializando this ), ou um object de substituição explícito não foi retornado, a linha final da chamada de construtor lançará uma exceção.

Houve várias respostas e comentários afirmando que o super DEVE ser a primeira linha dentro do constructor . Isso é simplesmente errado. A resposta @loganfsmyth tem as referências necessárias dos requisitos, mas resume-se a:

Inheriting ( extends ) constructor deve chamar super antes de usar this e antes de retornar mesmo que this não seja usado

Veja o fragment abaixo (funciona no Chrome …) para ver por que pode fazer sentido ter instruções (sem usar this ) antes de chamar super .

 '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()); 

A nova syntax da class es6 é apenas uma outra notação para “old” es5 “classs” com protótipos. Portanto, você não pode instanciar uma class específica sem definir seu protótipo (a class base).

Isso é como colocar queijo no seu sanduíche sem fazer isso. Também você não pode colocar queijo antes de fazer o sanduíche, então …

… usar this palavra this chave antes de chamar a superclass com super() também não é permitido.

 // 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"; } } 

Se você não especificar um construtor para uma class base, a seguinte definição será usada:

 constructor() {} 

Para classs derivadas, o seguinte construtor padrão é usado:

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

EDIT: Encontrado isso no developer.mozilla.org :

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

Fonte

Acabei de me cadastrar para postar essa solução, já que as respostas aqui não me satisfazem o mínimo, já que existe uma maneira simples de contornar isso. Ajuste seu padrão de criação de class para sobrescrever sua lógica em um submétodo enquanto usa apenas o superconstrutor e encaminhe os argumentos dos construtores para ele.

Como em você não cria um construtor em suas subclasss per se, mas apenas uma referência a um método que é sobrescrito na subclass respectiva.

Isso significa que você se liberta da funcionalidade de construtor aplicada a você e evita um método regular – que pode ser substituído e não impõe super () ao permitir que você escolha se, onde e como deseja chamar super (totalmente). opcional) por exemplo:

 super.ObjectConstructor(...) 
 class Observable { constructor() { return this.ObjectConstructor(arguments); } ObjectConstructor(defaultValue, options) { this.obj = { type: "Observable" }; console.log("Observable ObjectConstructor called with arguments: ", arguments); console.log("obj is:", this.obj); return this.obj; } } class ArrayObservable extends Observable { ObjectConstructor(defaultValue, options, someMoreOptions) { this.obj = { type: "ArrayObservable" }; console.log("ArrayObservable ObjectConstructor called with arguments: ", arguments); console.log("obj is:", this.obj); return this.obj; } } class DomainObservable extends ArrayObservable { ObjectConstructor(defaultValue, domainName, options, dependent1, dependent2) { this.obj = super.ObjectConstructor(defaultValue, options); console.log("DomainObservable ObjectConstructor called with arguments: ", arguments); console.log("obj is:", this.obj); return this.obj; } } var myBasicObservable = new Observable("Basic Value", "Basic Options"); var myArrayObservable = new ArrayObservable("Array Value", "Array Options", "Some More Array Options"); var myDomainObservable = new DomainObservable("Domain Value", "Domain Name", "Domain Options", "Dependency A", "Depenency B"); 

Você pode omitir super () em sua subclass, se você omitir o construtor completamente em sua subclass. Um construtor padrão ‘escondido’ será incluído automaticamente na sua subclass. No entanto, se você include o construtor em sua subclass, super () deve ser chamado nesse construtor.

 class A{ constructor(){ this.name = 'hello'; } } class B extends A{ constructor(){ // console.log(this.name); // ReferenceError super(); console.log(this.name); } } class C extends B{} // see? no super(). no constructor() var x = new B; // hello var y = new C; // hello 

Leia isto para mais informações.

Eu recomendaria usar o OODK-JS se você pretende desenvolver os seguintes conceitos de OOP.

 OODK(function($, _){ var Character = $.class(function ($, µ, _){ $.public(function __initialize(){ $.log('invoke character'); }); }); var Hero = $.extends(Character).class(function ($, µ, _){ $.public(function __initialize(){ $.super.__initialize(); $.log('invoke hero'); }); }); var hero = $.new(Hero); }); 

Experimentar:

 class Character { constructor(){ if(Object.getPrototypeOf(this) === Character.prototype){ console.log('invoke character'); } } } class Hero extends Character{ constructor(){ super(); // throws exception when not called console.log('invoke hero'); } } var hero = new Hero(); console.log('now let\'s invoke Character'); var char = new Character(); 

Demonstração

Solução simples: acho que não há necessidade de explicações.

 class ParentClass() { constructor(skipConstructor = false) { // default value is false if(skipConstructor) return; // code here only gets executed when 'super()' is called with false } } class SubClass extends ParentClass { constructor() { super(true) // true for skipping ParentClass's constructor. // code } }