JavaScript Inheritance – How To Shoot Yourself In the Foot With Prototypes!

When learning JavaScript, many beginners find it difficult to grasp the intricate details of how JavaScript’s prototypical inheritance works. In this article I will take a look at how to properly use the prototypical inheritance model with parent functions that have instance properties.

A Simple Widget Object

The following code has a Widget parent class that has a messages property and a SubWidget class that uses Widget as it’s parent class. In this case we want each instance of the SubWidget to be initialized with an empty messages array:

Before we set SubWidget’s prototype to a new instance of our Widget Prototype constructor, we get an object graph that looks like this:

The final line of code sets SubWidget’s parent class to a new instance of the Widget class. Using the ”new” keyword starts to tie everything together by beginning to create the inheritance tree and tying the scope of our objects together. Our object graph now looks something like this:

Do you see what the problem is yet? Lets create some instances of our subclass to highlight the issue:

Before I talk about the real problem here I’d like to step back and talk about the “type” property on the widget’s constructor. If it is not initialized by assignment each instance’s “type” property actually points to the constructor’s “type” property. However, once it is initialized by assigning a value like so: sub1.type = 'Fuzzy Bunny' it becomes a property of the instance, as shown in the new object graph:

Recognizing the Problem

Our bug should start to become clear now. Let’s log the value of both sub1 and sub2’s messages array:

Fixing the Problem

However, what if we wanted to create other objects that extended Widget? That new object would also need a messages array and pretty soon we have code that is a nightmare to maintain and extend. Additionally, what if we wanted to add other properties to the Widget constcutor that were initialized when instances of its sub-classes were constructed? This isn’t very reusable or flexible solution.

In order to properly fix this all that needs to be done is to add a single line of code to our SubWidget constructor that will invoke the Widget constructor with the same scope of our SubWidget constructor. To do this we use the apply ()method which will give us the flexibility to add additional arguments to the SubWidget constructor without having to change the call to Widget:

By using the apply() method we are changing the context in which the messages array is created to the instance of the SubWidget. Now when we create new objects each instance has a new instance of the messages array:

Very interesting article with nice graphs and presentation. The only question is what will happen if during execution we decide that our SubWidget shouldn’t inherit from Widget but from another object like “ChatWidget”. Then the prototype will be easy to change but the SubWidget is tightly coupled with Widget since we call apply during instantiation of “SubWidget”. Maybe a more robust approach and easier testable would be instead of :

This is a pretty tricky problem to get around indeed. Another solution that I’ve found very helpful (and more true to the classical inheritance model we see in other languages) is the one used (generated) by TypeScript (http://www.typescriptlang.org/). Basically, they define an inheritance function, __extends, as follows:
var __extends = this.__extends || function (d, b) {
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};

Now, the same example you showed above could be expressed with the following:

While this syntax is a bit more verbose (keep in mind, it’s generated by TypeScript from a ECMA6 class declaration), it has the benefit of allowing parameters to be passed into the base constructor and avoiding having the base constructor being called to instantiate the derived prototype. It also works well with instanceof calls. Here’s a less trivial example:

I guess there are some problems with the examples. On the first one, seems that code is already correct, as it is using `apply` passing the correct scope. And on the fifth one, shouldn’t it be `Widget.apply( this, Array.prototype.slice.call(arguments) );`?

Visiting the original article, this was also pointed out in this comment: http://blog.bittersweetryan.com/2013/05/javascript-inheritance-howto-shoot.html?showComment=1370613761670#c5228254175426976768

The very first diagram makes perfect sense, naturally, but wouldn’t the second diagram simply be a chart where the ‘prototype’ property of Widget draws an arrow directly to SubWidget (and, at the same time, SubWidget’s ‘__proto__’ property draws an arrow to Widget)?

Additionally, while the solution works as you intended in the post, it seems to entirely defeat the purpose of inheritance. It looks like you ended up with two separate objects anyway — why wouldn’t you simply define two objects? If they need to share properties, use normal references (properties) to point at the shared object.

From what I understand, the benefit of prototypal inheritance is similar to the benefits of classical inheritance: The ability to allocate less memory by choosing to “share” (extend) existing structured data. Since the data was only ever allocated once, it naturally “updates” the objects which extend it, if it changes on the source object (Class).

console.log(destination); //”Mars”
/* With proxies, there is no need to “extend” the properties to a sub-type. Instead, invoking objects can simply leverage the proxy API (like we do with jQuery, underscore, etc.) */

I wrote this on my phone… Hope it works! Someone please correct me if my understanding is wrong.

Oh boy, I just started a series of articles which tackles the some troubles. I’m glad to see I’m not alone…
http://opensas.wordpress.com/2013/06/09/troubleshooting-javascript-humble-homage-to-wat/
I hope you find it useful

In the first section of the article, you said this “Before we set SubWidget’s prototype to a new instance of our Widget Prototype constructor, we get an object graph that looks like this:”, and when viewing the graph, you can clearly see no properties are being shared between each object.

With that said, could you please explain what this line is doing;

Widget.apply( this, Array.prototype.slice.call( arguments ) );

I am completely confused by this, and I was wondering if this is necessary for the prototypical inheritance at all?

One of the most commonly used inheritance in JavaScript is Combination Inheritance (Prototype Chaining + Constructor stealing). Neither Prototype Chaining nor Constructor stealing should be used on their own, if used it will cause unexpected results as shown in the article.