JavaScript: Understanding Prototype & Inheritance

, , …,

Every JavaScript object O has a Internal Slot named “prototype”, usually denoted by “[[Prototype]]”.

The value of the [[Prototype]] is some object P (or null). 〔➤ JavaScript: What's Object?ECMAScript 2015 §Ordinary and Exotic Objects Behaviours#sec-ordinary-object-internal-methods-and-internal-slots-getprototypeof

The object P is called the “prototype object” of O. (we'll call it “parent object”.)

When a property is looked up (⁖ x.color), JavaScript looks at the object to see if it has that property, if not, it looks up its parent, and repeat, until a property is found or a parent is null. This is the technical meaning of inheritance in JavaScript.

A object's parent of parent of parent etc forms a chain. This is called a prototype chain. ECMAScript 2015 §ECMAScript Data Types and Values#sec-invariants-of-the-essential-internal-methods

Note: the prototype chain is never circular, and is impossible to create circular prototype chain.

Note: not all object have a parent, but buildin object does (except Object.prototype, which is the root, having parent of null).

You can easily creat a object without parent by Object.create(null). 〔➤ JavaScript: Creating Object with Object.create()

JavaScript Object Hierarchy

JavaScript object tree
JavaScript Object Hierarchy diagram.

How to Find a Object's Parent?

JavaScript: How to Find Object's Prototype/Parent?

How to Create Object with Specified Parent?

JavaScript: How to Create Object with Parent X?

a.b.c.d ≠ Parent Chain

When you see a.b.c.d in JavaScript, it has very different meaning than Java or Python, Ruby. This is a major point of confusion.

In Java, in a.b.c.p, the dot means parent/child except the last dot, is object/property. So, a is parent of b, b is parent of c, and c is the object that has member p.

In JavaScript, dot always means object/property relationship. There's no direct syntax to show parent chain.

in JavaScript, when you see a.b.c.d, the left/right thing of any dot has a object/property relationship.

It's parsed like this: (((a).b).c).d.

The value of the property, such as a.b, could be any object, having nothing to do with any of the object a or a.b or a.b.c.

For example, the object

Parent of Buildin Objects

The parent of {Object, Function, Array, Date, RegExp} is Function.prototype. Because, they are functions (more specifically, constructor functions. 〔➤ JavaScript: What's Constructor?〕 ). All function's parent is Function.prototype, by default.

 Object.getPrototypeOf(Object)   === Function.prototype &&
 Object.getPrototypeOf(Function) === Function.prototype &&
 Object.getPrototypeOf(Array)    === Function.prototype &&
 Object.getPrototypeOf(Date)     === Function.prototype &&
 Object.getPrototypeOf(RegExp)   === Function.prototype &&
); // true

The parent of {Math, JSON} is Object.prototype.

The Math & JSON objects are used as namespace for “static functions”. Math and JSON are not functions. 〔➤ JavaScript Math Object & Methods〕 〔➤ JavaScript JSON Object & Methods

    Object.getPrototypeOf(Math) === Object.prototype &&
    Object.getPrototypeOf(JSON) === Object.prototype &&
); // true

The parent of Function.prototype is Object.prototype.

    Object.getPrototypeOf(Function.prototype) === Object.prototype
); // true

Each of the {Function, Array, Date, RegExp} function object has a property named “prototype”. 〔➤ JavaScript: Property Named “prototype”

For example, you can eval the expression Array.prototype. That means, accessing a property named “prototype” from the object Array. The value of Array.prototype, is a object. There is no special syntax to express this object other than accessing property syntax such as Array.prototype or Array["prototype"].

These objects: {Function.prototype, Array.prototype, Date.prototype, RegExp.prototype} serve as parents of user created objects of particular sub-datatype. These objects's parent is Object.prototype. 〔➤ JavaScript Data Types

 Object.getPrototypeOf(Function.prototype) === Object.prototype &&
 Object.getPrototypeOf(Array.prototype)    === Object.prototype &&
 Object.getPrototypeOf(Date.prototype)     === Object.prototype &&
 Object.getPrototypeOf(RegExp.prototype)   === Object.prototype &&
); // true

Root of All Objects is 「Object.prototype」

The root of all JavaScript standard objects is Object.prototype. Itself doesn't have any parent. Its parent is null.

Object.getPrototypeOf(Object.prototype) === null // true

Note: it is possible to have a object without parent.

// creating object without parent
var tt = Object.create(null);
    Object.getPrototypeOf(tt) === null
); // true

〔➤ JavaScript: Creating Object with Object.create()

Parent of User Created Objects

// parent of user created objects

    Object.getPrototypeOf({})                === Object.prototype   &&
    Object.getPrototypeOf(function ff () {}) === Function.prototype &&
    Object.getPrototypeOf([])                === Array.prototype    &&
    Object.getPrototypeOf(/./)               === RegExp.prototype   &&
    Object.getPrototypeOf(new Date())        === Date.prototype
); // true

Parent of Object Created by Constructor Function

The parent of object created by new F(…) is:

// example of inheritance by constructor

var o1 = {};
var FF = function () { };
FF.prototype = o1;
var o2 = new FF();

console.log( Object.getPrototypeOf(o2) === o1 ); // true

Another example, using the default constructor function Date:

// example of inheritance by constructor
var dd = new Date();
console.log( Object.getPrototypeOf(dd) === Date["prototype"]); // true

〔➤ JavaScript: What Does Keyword “new” Do?

Like what you read? Please tell friends, share link, or Buy JavaScript in Depth. Thanks.
blog comments powered by Disqus