Adventures in Object-oriented JavaScript

Ok, I admit it. I used to think that JavaScript was a toy language. I think we all did. But even now that I’ve started treating it as a serious language, it still carries this stigma that it started life in Santa’s Workshop. For example, my approach to JavaScript for many years was to treat it as a serious functional language that had “prototypes” tacked on as a toy-like way to mimic classes and class-based inheritance.1

With that attitude, I was naturally excited to see JavaScript getting more Java-like classes in its latest update, ECMAScript 6 (commonly shortened to “ES6”). At the end of his excellent article, Dr. Rauschmayer writes, “I would have preferred [classes] to be prototypal (based on constructor objects, not constructor functions).” I thought to myself, Why are constructor objects better than constructor functions? And so, I started to do a little research.

That rabbit hole ate a week of my life.

At this point, I don’t even recall all the twists and turns that my research took. I do know that every time I thought I was getting a handle on it, I would read something new that threw my whole understanding into disarray. I read that prototypal inheritance matters, and then I read some comments on Stack Overflow, posted almost a year later, where the author repudiated his own blog post. I took a detour into why JavaScript needs types, an argument put forth by a lead developer on AngularJS no less. There were a few other stops, too.

Eventually, I made my way to Eric Elliott’s summary of JavaScript’s prototypal patterns and his StampIt module. I dug into its source code. Then I ruminated on Mozilla’s documentation of Object.create and the new operator. I went back and forth—probably consulted some other sources, too—and that’s when it happened.

I broke through.

I became illuminated.

I could see the FNORD​s!

And now, like Prometheus, I will share this divine knowledge with you, dear reader. Here is what the ancient and holy seers imparted to me through the illuminated intertwinings of the mystical web:2 CLASS-BASED IN­HER­IT­ANCE AND PRO­TO­TYP­AL IN­HER­IT­ANCE ARE MATH­E­MAT­IC­ALLY IN­DIS­TIN­GUISH­A­BLE.

Let me put that in less grandiose terms. There seems to be a lot of arguing about the value of prototypal inheritance versus class-based inheritance.3 These arguments are all focused on prototypes and classes without realizing that inheritance is inheritance.

Inheritance is inheritance.

I feel like that still needs to be unpacked more. Inheritance, of course, is the concept of defining a property on one thing—a parent—and then making that property available on other things that are related to the parent—the children. Pretty simple, right?

Does it matter if the parent is a “class” and each child is an “object”? Or if the parent is an “object” and each child is also an “object”?

No, of course not. We still have a parent, and we still have children. The relationship between the parent and the children is the same—it’s still inheritance. And the same rules apply to inheritance,4 whether the parent is an object or a class.

I feel like this is a major insight, because I haven’t seen it anywhere else. Instead, there’s all this other stuff—like all the cool stuff that StampIt does—that gets lumped into “prototypal inheritance” that isn’t actually inheritance. It’s something else. Something very cool and very powerful, but it’s not inheritance.

It’s also a topic for another time; I feel like I’ve rambled enough for one article. In the meantime, dwell on this insight. Ponder it. Am I onto something here, or am I full of it?

  1. This is commonly referred to as “classical inheritance,” which always sounds to me like “classical music”—like it’s really old or the only proper way of doing things. I use a slightly different term to clarify that there’s nothing particularly old school about classes. [return]
  2. Don’t let my silliness—and inability to take myself seriously—prevent you from taking this insight seriously. [return]
  3. Exclusively by hardcore JavaScript nerds. Perhaps because we’re the only ones who realize that classes aren’t the only way to handle inheritance. [return]
  4. Like the Liskov substitution principle. [return]