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:

  1. var Classroom = {
  2. welcome() {
  3. console.log("Welcome, students!");
  4. }
  5. };
  6. var mathClass = Object.create(Classroom);
  7. mathClass.welcome();
  8. // 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:

  1. function Classroom() {
  2. // ..
  3. }
  4. Classroom.prototype.welcome = function hello() {
  5. console.log("Welcome, students!");
  6. };
  7. var mathClass = new Classroom();
  8. mathClass.welcome();
  9. // 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:

  1. class Classroom {
  2. constructor() {
  3. // ..
  4. }
  5. welcome() {
  6. console.log("Welcome, students!");
  7. }
  8. }
  9. var mathClass = new Classroom();
  10. mathClass.welcome();
  11. // 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”.