# Error expected when super constructors invoke private methods in derived classes?

**URL:** <https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185>\
**Category:** I have questions\
**Created:** [February 1, 2022, 11:51pm UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185 "2022-02-01T23:51:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)\
**Post date:** [February 1, 2022, 11:51pm UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/1 "2022-02-01T23:51:06Z")

</div>

I've noticed error when a constructor in an inherited class leads to the invocation of a derived private method. Instead of being able to call the method, it fails with a TypeError. Example:

```javascript
class Base {
    constructor () {
        this.method()   
    }
    method() {}
}

class Derived extends Base {
    #priv(){}
    method() {
        this.#priv()
    }
}

new Derived()
// Chrome 97: Uncaught TypeError: Object must be an instance of class Derived
// Firefox 97: Uncaught TypeError: can't access private field or method: object is not the right class
// Safari 15.3: TypeError: Cannot access private method or acessor (evaluating 'this.#priv')

```

Shouldn't the instance in Base's constructor be a Derived object when constructing via the Derived constructor?

I originally noticed this trying to extend `Map`.

```javascript
class MyMap extends Map {
    #log(name){ 
        console.log(this, 'called', name)
    }
    set(key, value) {
        this.#log('set')
        return super.set(key, value)
    }
}
new MyMap([['a', 1]]) // TypeError ...

```

This happens with each of the keyed collections because they each internally call `set()` in their constructors (assuming they're provided iterables to pull from).

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [February 2, 2022, 2:07am UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/2 "2022-02-02T02:07:18Z")

</div>

Yes, this is expected, because the private fields aren’t installed until super is finished. Which means, you explicitly can’t have the superclass invoke code in the subclass that depends on having a fully constructed instance.

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [February 2, 2022, 4:02am UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/3 "2022-02-02T04:02:42Z")

</div>

Across many languages the general advise seems to be: avoid calling virtual functions from a constructor.

If the constructor needs something from a subclass it can be passed in explicitly as a constructor argument.

---

<div class="post-metadata">

**Author:** ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)\
**Post date:** [February 2, 2022, 4:29am UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/4 "2022-02-02T04:29:39Z")

</div>

Should keyed collection constructors not be calling set() then?

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [February 2, 2022, 7:51am UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/5 "2022-02-02T07:51:29Z")

</div>

There are people who think that was a mistake yes.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [February 2, 2022, 8:19am UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/6 "2022-02-02T08:19:16Z")

</div>

After recently trying to subclass `Map` with a private field, I whole heartedly concur on that. It's at best useless.

---

<div class="post-metadata">

**Author:** ![mbrowne](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mbrowne/32/1140_2.png) [@mbrowne](https://es.discourse.group/u/mbrowne)\
**Post date:** [February 8, 2022, 10:03am UTC](https://es.discourse.group/t/error-expected-when-super-constructors-invoke-private-methods-in-derived-classes/1185/7 "2022-02-08T10:03:53Z")

</div>

Interesting. This is probably a case where it would be better to use composition instead of inheritance.
