MDN is my go-to reference for anything web-related, even before doing a web search. But at times, it is structured too much as a reference guide, spreading over single pages every object property, every feature, every method... Which makes harder to get a general glimpse of a specific topic.
I wanted a quick refresh on what you can and cannot do, with Javascript, regarding classes, as of early 2023. I knew about class constructors, inheritance and recalled something about getters and setters, but for example I didn't knew about private scoping or the existence of static
(I was going to go for the classic prototype modification). After reading everything about JS classes, I've written this small example containing an example of mostly everything on the topic of classes in JS:
// definition
class Movable {
// public properties (can have default value)
x;
y;
// constructor
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
// getter
get position() {
return [this.x, this.y];
}
// normal method
move(x, y) {
this.x = x;
this.y = y;
}
}
// inheritance
class Robot extends Movable {
// private property + default value
#movements = 0;
// static property (can also be private) + default value
static CAN_MOVE = true;
// class constructor
constructor(x = 0, y = 0) {
// invoking parent constructor
super(x, y);
// not needed because of default value, but could do:
// this.#movements = 0;
}
// static class constructor/initializer
// static {}
// getter
get movements() {
return this.#movements;
}
// setter
set movements(value) {
this.#movements = value;
}
// prepend `async` on methods when corresponds
// normal method
move(x, y) {
// invoking parent method
super.move(x, y);
this.#movements++;
}
countAllMovements() {
// invoking private method
for (const count of this.#countMovements()) {
console.log(`Movement #${count + 1}`);
}
}
// static method
static canMove() {
// static properties must be used via class
return Robot.CAN_MOVE;
}
// generator method + private method
*#countMovements() {
let counter = 0;
while (counter < this.#movements) {
yield counter++;
}
}
}
// instantiation
const myRobot = new Robot(5, 5);
// static methods must be invoked via class
console.log(Robot.canMove());
myRobot.move(7, 7);
myRobot.move(9, 9);
myRobot.move(10, 7);
console.log(myRobot.position, myRobot.movements);
myRobot.countAllMovements();
myRobot.movements = 0;
console.log(myRobot.movements);