What are Object Prototypes? - Explaining Prototype Inheritance in a Simple Way

What are Object Prototypes? - Explaining Prototype Inheritance in a Simple Way

Object prototype and it's linking mechanism in plain English

Before we begin diving into what how [[Prototype]] inheritance works and what it entails, we will need to understand one interesting fact about JavaScript:

If you have seen a code written in ES6 or even React, you are most likely to have come across the ES6 class along with class-based terms like super() and constructor(). This may mislead you into thinking that JavaScript is traditionally a class-oriented language, which isn’t true.

Class Definition

In traditional class-oriented languages, a class acts as a blueprint. When you instantiate a class, the class is actually copied into its instance (object). The same behaviour occurs when a subclass extends a superclass. This behavior is analogous to the building plan in the blueprint of a house being copied to build an actual house.

When you make a constructor call with the new keyword, a copy operation occurs.

But with JavaScript, this is not the case. There is no class. What we have is an ordinary function being used to ‘construct’ an object.

function ordinaryFunction () {
  console.log('I am not a class, just an ordinary function');
}

const ords = new ordinaryFunction();

Most importantly, a ‘copy operation’ does not occur. Instead, a new object is created. This new object is linked to the prototype object, which brings to the main question.

WHAT IS A PROTOTYPE OBJECT?

The [[Prototype]] mechanism is a mechanism which links objects to other objects in some kind of chain, the prototypal chain. This behaviour underpins the whole nature of JavaScript.

function Foo() {
// ...
}
var b = new Foo();
Object.getPrototypeOf( b ) === Foo.prototype; // true

The getPrototype() static method checks for the prototype object of b. Here, it indicates that object (b) is actually linked to the foo.prototype object.

To be thorough, whenever a constructor call (new...) is made, an object is created. That newly created object will link to an object with is referenced to by the fn.prototype property, which incidentally is the prototype object of that chain.

NOTE: In fn.prototype, the fn is just any function used to make the call. In our case it was Foo. It could also be CalculateHeight, SuccessMessage or any other simple function in your JavaScript.

In other words, when the new call is made, the newly created object b will get an internal [[Prototype]] link to the object which Foo.prototype is pointing at.

function Foo() {
// ...
}

Foo.prototype; // { }

If you know of true class-oriented languages, you know that in class inheritance a copy of the class is used to construct an object. However, with prototypal inheritance of JavaScript, a link is created through which objects on the top of the chain can delegate access of its properties and methods to objects lower on the chain:

protypal chain.png

The Fn.prototype Object (aka Prototype Object)

Here’s something interesting to know. The fn.prototype object has a couple of in-built properties in it, one of them is the ‘constructor’ property.

function Baz() {
// ...
}

Baz.prototype.constructor === Baz; // true
// Here, the constructor property references the function the prototype object is linked to.

var b = new Baz();

b.constructor === Baz; // true

The object b is created from the constructor call with Baz function. This begs the question: How is it able to get access to the constructor property even though such property was never directly defined in the object? The answer? It is via [[Prototype]] delegation.

All object prototypes (like baz.prototype) comes with an in-built constructor property. Thus, thanks to prototypal inheritance, any other objects linked to that prototype object (via new construcutor call) will automatically have access to that property along with the following other in-built properties:

  • hasOwnProperty()
  • isPrototypeOf()
  • propertyIsEnumerable()
  • toString()
  • toLocaleString()
  • hasOwnProperty()
  • valueOf()

It is however important to note that the in-built prototype object can be overridden:

function Bar() { /* .. */ }
Bar.prototype.constructor = // Bar
Bar.prototype = { /* .. */ }; // overrides the on-built object, assigns a new prototype object

var boo = new Bar();
boo.constructor === Bar; // false!
boo.constructor === Object; // true!

To illustrate how prototypal inheritance truly works, lets consider the following example

function Foo(title) {
this.title= title;
}

Foo.prototype.myTitle = function() {
return this.title;
};

var a = new Foo( "king" );
var b = new Foo( "queen" );

a.myTitle(); // "king"
b.myTitle(); // "queen"

Two separate objects are created, a and b. Here are two important points which essentially summarizes how prototypal inheritance (object delegation) works:

  1. When both objects were created with new, a parameter was passed in to the constructor function (Foo). This parameter is then stored into both instance objects as the title property (with this referring to the context objects).

  2. You may not be surprised to find the myTitle() method call working despite the fact that the method was never defined and is not present in either a or b. If you are surprised, then this is why:

Foo.prototype.myTitle = function() {
return this.title;
};

The myTitle() method was passed as a method into the foo.protoype object, which is the highest on the prototypal chain. So even when both a and b didn’t have the myTitle method present in each of them, they both had access to the prototype object because they are linked to it. So all they had to do was climb up and access it from there.

This is basically all you need to know about the [[Protoype]] mechanism in JavaScript. It enables objects link and delegate access to each other in a form of chain. That way, objects lower on the chain can have access to properties and methods in objects higher on the chain.

We’ll leave that for our next episode of the Explain like I’m 5 series.

P/S: If you like articles like this follow this blog to never miss an update. If you are learning JavaScript, you’ll definitely want to check out my JavaScript Notes.

 
Share this