1

I want to create a class hierarchy in vanilla JavaScript where a base class defines a common architecture and several inheriting classes add fields and functionality to it.

I don't understand why a subclass field not present in the base class remains undefined when it is set in an overridden function in the subclass via the base class constructor.

Is this to do with the scope of this in the baseclass constructor? What would be the correct way of doing something like this?

//A base class with just one field
class Base{

    field1;
    
    constructor(){
        //Call an overridden function of a subclass if it has been defined
        this.setParameters();
    }
  
    setParameters(){
        this.field1 = "BASE_VALUE"
    }
}

//A subclass with the field of the base one and an additional unique field
class Sub extends Base{

    field2;

    //Override the base class function
    setParameters(){
        this.field1 = "SUB_VALUE_1";
        this.field2 = "SUB_VALUE_2";
    }

}

var base = new Base();
console.log(base); // field1 is "BASE_VALUE" as expected

var sub = new Sub();
console.log(sub); // field2 is undefined but I would expect it to be "SUB_VALUE_2"
dubious
  • 155
  • 2
  • 7
  • 2
    Because `field2;` re-initialises the property to `undefined` when the parent constructor exits. [Do not call overridden methods from the constructor](https://stackoverflow.com/questions/4575448/calling-an-overridden-method-from-base-constructor), [not](https://stackoverflow.com/q/30819663/1048572) [in](https://stackoverflow.com/q/3404301/1048572) [any](https://stackoverflow.com/q/2898422/1048572) [language](https://stackoverflow.com/q/6858842/1048572)! – Bergi May 29 '21 at 12:54
  • @Bergi I see, thank you. Is this a fundamental behaviour of JS or have I set it up wrong? Can I stop this from happening? – dubious May 29 '21 at 12:57
  • 1
    It's a fundamental behaviour of OOP. Use `constructor` to initialise your instances, not `setParameters`. – Bergi May 29 '21 at 12:58

1 Answers1

0

A big issue here in your script is the use of a method for define fields, for define fields you need do it on constructor of class, here an example:

//A base class with just one field
class Base{

    constructor(){
        this.field1 = "base1";
    }
  
}

//A subclass with the field of the base one and an additional unique field
class Sub extends Base{

    constructor(){
        
        super();
        
        console.log(this.field1); //base1
        
        //Changing value of this.field1 and defining this.field2
        this.field1 = "SUB_VALUE_1";
        this.field2 = "SUB_VALUE_2";
    }

}

var base = new Base();
console.log(base); // field1 is "base1" as expected

var sub = new Sub();
console.log(sub);