# override constructor

{% tabs %}
{% tab title="💾 程式" %}
✅ case 1：<mark style="color:green;">none has constructor</mark>

```javascript
// no constructors
class A {}
class B extends A {}

let b = new B();        // ✅ OK
```

❌ case 2：<mark style="color:orange;">returning from derived constructor without calling</mark> <mark style="color:orange;"></mark><mark style="color:orange;">`super()`</mark> <mark style="color:orange;"></mark><mark style="color:orange;">first</mark>

```javascript
class A2 {}

class B2 extends A2 {
    constructor(){
        // ---------------------------------------------------
        // ⛔ ReferenceError: 
        //   Must call `super()` constructor in derived class 
        //   ☐ before accessing `this` or 
        //   ☑ returning from derived constructor
        // ---------------------------------------------------
    }
}

let b2 = new B2();
```

❌ case 3：<mark style="color:orange;">accessing</mark> <mark style="color:orange;"></mark><mark style="color:orange;">`this`</mark> <mark style="color:orange;"></mark><mark style="color:orange;">before calling</mark> <mark style="color:orange;"></mark><mark style="color:orange;">`super()`</mark>

```javascript
class A3 {}

// (accessing `this` before calling `super()`)
class B3 extends A3 {
    constructor(){
        // ---------------------------------------------------
        // ⛔ ReferenceError: 
        //   Must call `super()` constructor in derived class 
        //   ☑ before accessing `this` or 
        //   ☑ returning from "derived constructor"
        // ---------------------------------------------------
        this.name = "Joe"
    }
}

let b3 = new B3();
```

✅ case 4：

```javascript
class A4 {}

class B4 extends A4 {
    constructor(){
        
        // ⭐ "derived constructor" expects "parent (base) constructor"
        //    to create an empty object and assign it to `this`.
        super();

        // ✅ now it's OK to access `this`.
        this.name = "Joe";
    }
}

let b4 = new B4();
log(b4.name);            // Joe
```
{% endtab %}

{% tab title="⭐️ 重點" %}
🔸 **default derived constructor**

{% hint style="warning" %}
if a class <mark style="color:orange;">**extends**</mark> another class and has <mark style="color:red;">**no**</mark> <mark style="color:purple;">**constructor()**</mark>, then the following “<mark style="color:orange;">**default**</mark>” <mark style="color:purple;">**`constructor()`**</mark> is generated:

```javascript
class B extends A {
  constructor(...args) { super(...args) }  // ⭐️ auto-generated
}
```

👉 [JavaScript.info](https://javascript.info/class-inheritance#overriding-constructor)
{% endhint %}

🔸 **derived constructor**

{% hint style="info" %}
* When a <mark style="color:green;">**regular function**</mark> is executed with <mark style="color:purple;">**`new`**</mark>, it creates an <mark style="color:orange;">**empty object**</mark> and assigns it to <mark style="color:purple;">**`this`**</mark>.
* But when a <mark style="color:red;">**derived constructor**</mark> runs, it doesn’t do this. It expects the <mark style="color:orange;">**parent (base) constructor**</mark> to do the job.&#x20;
* So a <mark style="color:red;">**derived constructor**</mark> must call <mark style="color:purple;">**`super`**</mark> in order to execute its <mark style="color:orange;">**parent (base) constructor**</mark>, otherwise the <mark style="color:red;">**object**</mark> for <mark style="color:purple;">**`this`**</mark> **won’t be created**. And we’ll **get an error**.

👉 [JavaScript.info](https://javascript.info/class-inheritance#overriding-constructor)
{% endhint %}
{% endtab %}

{% tab title="📗 參考" %}
* [x] JS.info ⟩ [overriding constructor](https://javascript.info/class-inheritance#overriding-constructor)
{% endtab %}

{% tab title="👥 相關" %}
* [super](super "mention") is used in **derived constructor** or **overridden methods**.
{% endtab %}
{% endtabs %}
