Prototype inhertitance in JS

Tonight in New York City the Yeti is on the prowl. Fourteen inches of snow are forecast to fall by morning, and at the top of the food chain is a menacing monster. We can represent this beast as a JavaScript object to demonstrate prototype inheritance in JavaScript.

Notice that the yeti object is represented by a hash of key-value pairs. The first key, find, has a value that is a function. That function returns the value of the second key in the yeti hash, appetite, by using the “this” keyword as shorthand for “self” or “this object”. It is strange for an object to reflect on itself like this, but as an academic exercise, it illustrates inheritance very well. Things will get stranger. For now, just know that the this keyword always refers to an object.

To prove this works, let’s call .find on the yeti.

yeti.find();

//gigantic

So far so good, we returned exactly what was expected, the value of the yeti’s appetite. But here are many other hungry beasts in the blizzard and we want to display the value of their appetites too. How can we do this in Javascript? Well, first, we could create individual objects for each beast with their own find methods, but that would violate one of the tenants of object-oriented programming: don’t repeat yourself.

Instead, we’ll let each of our new objects inherit the find function from the abominable snow beast. Let’s go down the food chain to demonstrate the quirks of prototype inheritance in JavaScript and create a polar bear object that inherits from the yeti.

var polar_bear = Object.create(yeti);
polar_bear.appetite = “huge”;

Not being nearly as ferocious as the yeti, we set the polar bear’s appetite to “huge”. When we call .find on polar_bear, it will go up the prototype inheritance tree searching for the .find function. When it finds it in the yeti object, it will start evaluating the function and see the keyword “this”. Because this refers to the object that called the method, i.e., the polar bear, the value returned will be the value of the polar bear’s appetite(huge) — not the yeti’s(gigantic).

polar_bear.find();  //huge

We can keep going down the food chain, creating descendants of the yeti who all inherit the find function from the dreaded monster. But prototype inheritance is tricky. For each new object, if we don’t declare an appetite variable, you might think that the object would instead inherit the yeti’s appetite, too, but that is not the case.

Prototype inheritance will refer to the appetite of the last ancestor in the inheritance chain that did have an appetite.

For example, When JavaScript sees the .find function called on the arctic hare object, it goes all the way up the chain until until if finds the function in the yeti. When JS sees the keyword “this” it goes back down the chain to the object that called .find (the snow mouse). Because the snow mouse has no appetite set, JS goes back up the inheritance chain again until it finds an appetite key-value pair. Once it finds a appetite variable (in the seal object) JS considers its work done and hands that key-value pair to the descendant object, the snow mouse.

The lesson is, when using prototype inheritance, we need to be very clear on how JavaScript will interpret the this keyword from a parent object to avoid inheriting erroneous appetites, such as big for the snow mouse.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s