Prototypal “Classes”
In Chapter 3, we introduced prototypes and showed how we can link objects through a prototype chain.
Another way of wiring up such prototype linkages served as the (honestly, ugly) predecessor to the elegance of the ES6 class
system (see Chapter 2, “Classes”), and is referred to as prototypal classes.
TIP: |
---|
While this style of code is quite uncommon in JS these days, it’s still perplexingly rather common to be asked about it in job interviews! |
Let’s first recall the Object.create(..)
style of coding:
var Classroom = {
welcome() {
console.log("Welcome, students!");
}
};
var mathClass = Object.create(Classroom);
mathClass.welcome();
// Welcome, students!
Here, a mathClass
object is linked via its prototype to a Classroom
object. Through this linkage, the function call mathClass.welcome()
is delegated to the method defined on Classroom
.
The prototypal class pattern would have labeled this delegation behavior “inheritance,” and alternatively have defined it (with the same behavior) as:
function Classroom() {
// ..
}
Classroom.prototype.welcome = function hello() {
console.log("Welcome, students!");
};
var mathClass = new Classroom();
mathClass.welcome();
// Welcome, students!
All functions by default reference an empty object at a property named prototype
. Despite the confusing naming, this is not the function’s prototype (where the function is prototype linked to), but rather the prototype object to link to when other objects are created by calling the function with new
.
We add a welcome
property on that empty object (called Classroom.prototype
), pointing at the hello()
function.
Then new Classroom()
creates a new object (assigned to mathClass
), and prototype links it to the existing Classroom.prototype
object.
Though mathClass
does not have a welcome()
property/function, it successfully delegates to the function Classroom.prototype.welcome()
.
This “prototypal class” pattern is now strongly discouraged, in favor of using ES6’s class
mechanism:
class Classroom {
constructor() {
// ..
}
welcome() {
console.log("Welcome, students!");
}
}
var mathClass = new Classroom();
mathClass.welcome();
// Welcome, students!
Under the covers, the same prototype linkage is wired up, but this class
syntax fits the class-oriented design pattern much more cleanly than “prototypal classes”.