Imho, this is just about naming things. Some people call a concept Class, others call a similar concept Prototype. From a high enough view-point, they are the same. They are a blueprint to construct an object.
However, both are conceptually different. In JS, prototypes are run-time constructs, while classes are compile-time. They are not the same, if only for this argument (and there are more facts).
If you ask me, classes give the impression of a compile-time (write-time???) construct, however, under the hood, the JSVM treats them as prototype functions, which means a lot of confusion and many new JS devs who have trouble understanding in what ways "classes" can be manipulated at run-time.
JS is class-less. It has prototypes. Any good teacher or tutorial should explain the difference and naming conflict (as such). Intoducing the class-keyword was wrong, because it's something different.
// alternative how JS may have looked like, imho
// `name` will be a constructor parameter and be available as private field
// All inheritors have to declare it as well
const Animal = prototype(name) { // alternatively analog to `function`: prototype Animal(name) { //...
constructor() {
// define another private field:
proto.myInternalCounter = 0;
// `name` is a private field, make it publicly available:
this.name = name;
}
eat() { /* ... */ }
};
const Mammal = prototype() {
breed(otherMammal) { /* ... */ }
};
const Cat = prototype(name, furColor) inherits Animal mixes Mammal {
// `furColor` is a private field, expose it as protected field, too:
furColor: furColor;
hunt() { /* ... */ }
speak() { /* ... */ }
};
const myCat = new Cat('Mokka', 'brown');
const yourCat = new Cat('Snowflake', 'white');
myCat.hunt();
yourCat.eat();
console.log(myCat.name); // prints "Mokka"
const brood = myCat.breed(yourCat);