this.isLoud
is not the same thing as LoudSpeaker.isLoud
. The first refers to an instance variable, the second refers to a property of the LoudSpeaker constructor function which other languages would call a class variable or a static property. In Javascript, you do not refer to class variables using this.isLoud
.
To override the value of the instance variable isLoud
in a subclass, you would set its value in the constructor.
class Speaker {
constructor() {
this.isLoud = false; // set default value
}
sayHi() {
if (this.isLoud) {
console.log('HI');
} else {
console.log('hi');
}
}
}
class LoudSpeaker extends Speaker {
constructor() {
super();
this.isLoud = true; // override to set our own value
}
}
If you really want the isLoud
property to be something that a class sets once and is never set again, then you can set it on the prototype and then you can reference it with this.isLoud
from within an instance:
class Speaker {
sayHi() {
if (this.isLoud) {
console.log('HI');
} else {
console.log('hi');
}
}
}
Speak.prototype.isLoud = false; // set default value
class LoudSpeaker extends Speaker {
}
LoudSpeaker.prototype.isLoud = true; // override for this class
This is usually not done in Javascript because if you set this.isLoud = whatever
, then it sets an "own" property and the property becomes an instance property that is specific to that instance and that can be really confusing and bug causing. So, this is generally not done. If, however, you initialize the value on the prototype, never set it on the instance so you only read its value with x = this.isLoud
, then it does behave as a class variable that is accessible via this
.
There is discussion of this topic in the ES6 wiki. See ES6 class variable alternatives for details as this capability is intentionally left out of the ES6 class syntax which is why it's implemented here as either a regular instance variable set in the constructor or a property set directly on the prototype (and not via the class syntax).