Javascript ES6: "Super" and "Extends"
Published: 2020-07-06 13:17:20

Keywords `super` and `extends` are integral parts of Javascript's ES6 subclass syntax, but `super`'s role can seem mysterious. To get a better understanding of how they work, let's start with an example of inheritance in pseudoclassical ES6 pattern:
```javascript
class Bicycle {
  constructor(brand, color) {
    this.brand = brand;
    this.color = color;
  }

  describe() {
    return (`This bicycle is a ${this.color} ${this.brand}.`);
  }

  gearing(chainRings, cogs) {
    this.chainRings = chainRings;
    this.cogs = cogs;
    this.speeds = this.cogs * this.chainRings;
    if (this.speeds > 1) {
      return (`This ${this.brand} is a ${this.speeds}-speed.`);
    }
    if (this.speeds === 1) {
      return (`This ${this.brand} is a single-speed.`);
    }
  }
}

const pug = new Bicycle("Peugeot", "red");
console.log(pug.describe()); /* This bicycle is a 
red Peugeot. */
```
In the example above, the `Bicycle` class has a constructor function to create a `Bicycle`, and a method, `gearing`, to report its gearing. Note the `class` keyword, and capitalization of the class name, `Bicycle`, both of which are important components of this instantiation pattern. A new instance of a `Bicycle` is created with the keyword `new`.

Now, on to the subclass business. Let's create a subclass `Fixie` that takes on `Bicycle`'s properties.
```javascript
class Fixie extends Bicycle {
    constructor(brand, color) {
      this.chainRings = 1;
      this.cogs = 1;
      this.isFixedGear = true;
    }

    gearing() {
      if (this.isFixedGear === true) {
        return (`This ${this.brand} is a fixed-gear.`);
      }
    }
}
```
It's easy to see that `extends` directs subclass `Fixie` to take on class `Bicycle`'s properties (much like the underscore library's `extend` method extends an object(s) properties into another). `Fixie`, however, has its own constructor that adds properties, and it overrides one of its inherited methods, `gearing`. 

What's less apparent here is that this code won't work as written. Attempting to create a new instance of `Fixie` will throw a `ReferenceError` Specifically, mine says `Must call super constructor in derived class before accessing 'this' or returning from derived constructor`—if only all errors were this helpful! We'll need to user `super` somehow to get things up and running—but how? And why? 

According to [javascript.info](https://javascript.info/class-inheritance), "In JavaScript, there’s a distinction between a constructor function of an inheriting class (so-called “derived constructor”) and other functions." The problem is a derived constructor called with keyword `new` does not create an empty object assigned to `this`, because it "expects the parent constructor to do this job." So all we have to do is call the constructor in super (the parent class)—fair enough. Here's another go at it:

```javascript

class Fixie extends Bicycle {
    constructor(brand, color) {
      super(brand, color);
      this.chainRings = 1;
      this.cogs = 1;
      this.isFixedGear = true;
    }

    gearing() {
      if (this.isFixedGear === true) {
        return (`This ${this.brand} is a fixed-gear.`);
      }
    }
}


const moto = new Fixie("Motobecane", "blue");
console.log(moto.gearing()); /* This Motobecane is a
fixed-gear. */
```

The important thing to note is that `super` *must* be called before any use of keyword `this`, or there will be no `this` to refer to, and an error will be thrown. Now let's look at one more use of `super`:
```javascript
class Fixie extends Bicycle {
    constructor(brand, color) {
      super(brand, color);
      this.chainRings = 1;
      this.cogs = 1;
      this.isFixedGear = true;
    }

    gearing() {
      if (this.isFixedGear === true) {
        return (`This ${this.brand} is a fixed-gear.`);
      }
    }

    describe() {
      return `${super.describe()} This bike is a fixie.`
    }
}

console.log(moto.describe()) /* This bicycle is a blue
Motobecane. This bike is a fixie. */
```
Now we've used a call of the `super`'s `describe` method while actually overriding `describe` within the subclass. The new method will return the value of `describe`'s message from the `Bicycle` class along with more information describing the bike as a fixie. 

Keyword `super` doesn't have to be mysterious! Just remember that it refers to the parent class (thinking "superclass" may help), and that it must be called in the subclass's constructor function to start up a new empty object for keyword `this`. 
*Super!*