super() on class that extends

Axel Rauschmayer axel at rauschma.de
Sat Apr 11 00:06:06 UTC 2015


The reason why you need to call the super-constructor from a derived class constructor is due to where ES6 allocates instances – they are allocated by/in the base class (this is necessary so that constructors can be subclassed that have exotic instances, e.g. `Array`):

```js
// Base class
class A {
    // Allocate instance here (done by JS engine)
    constructor() {}
}
// Derived class
class B extends A {
    constructor() {
        // no `this` available, yet
        super(); // receive instance from A
        // can use `this` now
    }
}
// Derived class
class C extends B {
    constructor() {
        // no `this` available, yet
        super(); // receive instance from B
        // can use `this` now
    }
}
```

If you do not call `super()`, you only get into trouble if you access `this` in some manner. Two examples:

```js
// Derived class
class B1 extends A {
    constructor() {
        // No super-constructor call here!
      
        // ReferenceError: no `this` available
        this.foo = 123;
    }
}
// Derived class
class B2 extends A {
    constructor() {
        // No super-constructor call here!
      
        // ReferenceError: implicit return (=access) of `this`
    }
}
```

Therefore, there are two ways to avoid typing super-constructor calls.

First, you can avoid accessing `this` by explicitly returning an object from the derived class constructor. However, this is not what you want, because the object created via `new B()` does not inherit `A`’s methods.

```js
// Base class
class A {
    constructor() {}
}
// Derived class
class B extends A {
    constructor() {
        // No super-constructor call here!
        
        return {}; // must be an object
    }
}
```

Second, you can let JavaScript create default constructors for you:

```js
// Base class
class A {
}
// Derived class
class B extends A {
}
```

This code is equivalent to:

```js
// Base class
class A {
    constructor() {}
}
// Derived class
class B extends A {
    constructor(...args) {
        super(...args);
    }
}
```

> On 10 Apr 2015, at 22:51, Jacob Parker <jacobparker1992 at gmail.com> wrote:
> 
> Why was this a requirement? I have a class, we’ll call a, which I want to extend from b, but I don’t want to call the constructor. I just want to inherit a few functions from it.

-- 
Dr. Axel Rauschmayer
axel at rauschma.de
rauschma.de

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150411/9c69591a/attachment-0001.html>


More information about the es-discuss mailing list