Pillar 2: Prototypes
The second pillar of the language is the prototypes system. We covered this topic in-depth in Chapter 3 (“Prototypes”), but I just want to make a few more comments about its importance.
JS is one of very few languages where you have the option to create objects directly and explicitly, without first defining their structure in a class.
For many years, people implemented the class design pattern on top of prototypes—so-called “prototypal inheritance” (see Appendix A, “Prototypal ‘Classes’”)—and then with the advent of ES6’s class
keyword, the language doubled-down on its inclination toward OO/class-style programming.
But I think that focus has obscured the beauty and power of the prototype system: the ability for two objects to simply connect with each other and cooperate dynamically (during function/method execution) through sharing a this
context.
Classes are just one pattern you can build on top of such power. But another approach, in a very different direction, is to simply embrace objects as objects, forget classes altogether, and let objects cooperate through the prototype chain. This is called behavior delegation. I think delegation is more powerful than class inheritance, as a means for organizing behavior and data in our programs.
But class inheritance gets almost all the attention. And the rest goes to functional programming (FP), as the sort of “anti-class” way of designing programs. This saddens me, because it snuffs out any chance for exploration of delegation as a viable alternative.
I encourage you to spend plenty of time deep in Book 3, Objects & Classes, to see how object delegation holds far more potential than we’ve perhaps realized. This isn’t an anti-class
message, but it is intentionally a “classes aren’t the only way to use objects” message that I want more JS developers to consider.
Object delegation is, I would argue, far more with the grain of JS, than classes (more on grains in a bit).