Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Child class member initializer overriding parent class constructor

If I have a super class that is supposed to be able to set some initial properties on a new instance, why do the members of the child class seem to override the constructor of the super class?

class Base {
  constructor(fields) {
    Object.assign(this, fields)
  }
}

class Foo extends Base {
  time = 0;
  
  // calling super seems to make no difference
  // constructor(...args) {
  //  super(...args)
  // }
}

const foo = new Foo({ time: 22 })

console.log(foo.time) // is 0, should be 22?

If I remove time = 0; from the child class it works as expected but my linter breaks.

How can I retain the member initializer, i.e., time = 0; in the child class but have the super class be able to set properties in its constructor?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Instances may only be accessed after a super call is complete. Without the class field, look at the error:

class Base {
  constructor(fields) {
    Object.assign(this, fields)
  }
}

class Foo extends Base {
  constructor(...args) {
    this.time = 0;
    super(...args)
  }
}

const foo = new Foo({ time: 22 })

Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor

Class fields follow this same logic by assigning to the instance only after the super call is complete. So

class Foo extends Base {
  time = 0;
  
  constructor(...args) {
    super(...args)

is equivalent to

class Foo extends Base {
  constructor(...args) {
    super(...args)
    this.time = 0;

In other words – the properties assigned inside the constructor (or class field) of a subclass is designed to override the properties assigned in a superclass constructor.

but have the super class be able to set properties in its constructor?

One approach would be to the default value for the time property to 0, then pass and use that instead of a class field:

class Base {
  constructor(fields) {
    Object.assign(this, fields)
  }
}

class Foo extends Base {
  constructor({ time = 0, ...rest }) {
    super({ time, ...rest })
  }
}

const foo = new Foo({ time: 22 })

console.log(foo.time)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading