Why Prototypal Inheritance Matters?

Prototype-based programming is a style of object-oriented programming in which behaviour reuse (known as inheritance) is performed via a process of cloning existing objects that serve as prototypes. This model can also be known as prototypal, prototype-oriented, classless, or instance-based programming. Delegation is the language feature that supports prototype-based programming.

Problem with classical Inheritance:

Most JavaScript programmers will tell you that classical inheritance is bad. However only a handful of them really know why. The truth is that classical inheritance is not bad. Python has classical inheritance and it’s a great programming language. Nevertheless classical inheritance is not suitable for JavaScript. Python got classes right. They are simply factory functions. In JavaScript however any function can be used as a constructor.

The problem with JavaScript is that since any function can be used as a constructor we need to distinguish a normal function call from a constructor function call; and this is achieved using the new keyword. However, this breaks functional features in JavaScript since new is a keyword, not a function. Hence functional features can’t be used in conjunction with object instantiation.

Classical vs Prototypal:

In prototypal inheritance, instances inherit from other instances. Using delegate prototypes (setting the prototype of one instance to refer to an examplar object), it’s literally Objects Linking to Other Objects, or OLOO, as Kyle Simpson calls it. Using concatenative inheritance, you just copy properties from an exemplar object to a new instance.

It’s really important that we understand these differences. Class inheritance by virtue of its mechanisms create class hierarchies as a side-effect of sub-class creation. Those hierarchies lead to arthritic code (hard to change) and brittleness (easy to break due to rippling side-effects when you modify base classes).

Prototypal inheritance does not necessarily create similar hierarchies. I recommend that you keep prototype chains as shallow as possible. It’s easy to flatten many prototypes together to form a single delegate prototype.

Understanding Prototypal Inheritance:

Prototypal inheritance is simple. In prototypal languages you only have objects. No classes. There are two ways to create new objects – ex nihilo (“out of nothing”) object creation or through cloning an existing object. In JavaScript the Object.create function (discovered by Douglas Crockford) is used to create new objects. Newly created objects are then extended with new properties.

Inheritance and the _proto_

When an object rabbit inherits from another object animal, in JavaScript that means that there is a special property rabbit.__proto__ = animal

When a rabbit property is accessed, and the interpreter can’t find it in rabbit, it follows the__proto__ link and searches in animal.

  1. var animal= { eats: true }
  2. var rabbit = { jumps: true }
  3. rabbit._proto_ = animal     //inherit
  4. alert (rabbit.eats)                  //true

The eats property is actually taken from animal. Here’s the picture: 

If the property is found in rabbit, then __proto__ is not checked.

For example, when eats is in the child object, parent is ignored:

  1.  var animal= { eats: true }
  2. var fedUpRabbit = { eats: false }
  3. fedUpRabbit._proto_ = animal     //inherit
  4. alert (fedUpRabbit.eats)                  //false

One could put a method into animal and it becomes available in rabbit:

  1. var animal = {
  2.       eat: function() {
  3.            alert( “I’m full” )
  4.            this.full = true
  5.     }
  6.  }
  7. var rabbit = {
  8.      jump: function() { /* something */ }
  9. }
  10. rabbit.__proto__ = animal
  11. rabbit.eat()


The
rabbit.eat() is executed in two steps:

  1. First, the interpreter looks up rabbit.eat. There’s no eat in rabbit object, so it goes torabbit.__proto__ and finds it there.

  2. The function runs with this = rabbit.The value of this is completely irrelevant to __proto__. It is set exactly to the object before the dot (see more about thishere).So, this.full = true stores the value in the rabbit object:

Look what we’ve got. An object calls parent method, but this is set to the object itself. That’s the inheritance.The object, referenced by __proto__ is called a prototype. So, animal is a prototype of rabbit.

Object.create (proto[,props])

Creates an empty object with given __proto__

  1. var animal ={ eats: true }
  2. rabbit= Object.create(animal)
  3. alert (rabbit.eats)                   //true

The code above creates empty rabbit with animal __proto__:

Once the rabbit is created, we can add properties to it.

Object.getPrototypeOf(obj)

Returns the value of obj.__proto__. The method is standard, so it works in browsers which don’t support __proto__ property.

The prototype

Remember, any function creates an object when called with new. A new function call sets the __proto__ of the object to the value of its prototype property.

  1. var animal = { eats: true }
  2. function Rabbit (name) {
  3.          this.name = name
  4. }
  5. Rabbit. prototype = animal
  6. var rabbit = new Rabbit (‘John’)
  7. alert (rabbit.eats)                // true because rabbit. _proto_ == animal

The code Rabbit.prototype = animal literally means the following:
”set __proto__ = animal for all objects created by new Rabbit.

hasOwnProperty

All objects have hasOwnProperty method which allows to check if a property belongs to the object or its prototype.

Conclusion:

It is essential to understand the prototypal inheritance model before writing complex code that makes use of it. Also, be aware of the length of the prototype chains in your code and break them up if necessary to avoid possible performance problems. Further, the native prototypes should never be extended unless it is for the sake of compatibility with newer JavaScript features.

Advertisements

Published by

gradgospels

I am a Software Engineer by profession. I'm ever curious to find the latest technology in the field and put it to good use. Quite a bit of my free time goes to learn different tools and technology.I enjoy development for Linux, building/leading teams, and contributing to different open source projects. Even though I have a very wide range of interests when it comes to build software, my current focus is on Frontend development. I am thrilled to work with HTML,CSS,JS, JQuery and Ajax like concepts. I also love to read, write, travel and cook.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s