Object Prototype

A Prototype is an object that can be inherited by another object. Javascript is an example of Prototype-based programming [1] where behaviors are reused using prototypes.

Every object in javascript has a default prototype Object.prototype which can be looked up using property __proto__ or simply using Object.getPrototypeOf method.

const obj = {
    age: 1
}
 
console.log(Object.getPrototypeOf(obj))
// {__defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, __lookupSetter__: ƒ, …}

Prototype chain

An object has prototype where prototype is an object. This prototype object can again have another prototype object, until it results into null which usually happens when Object.prototype reaches.

 
obj.__proto__ // returns Object.prototype
 
obj.__proto__.__proto__ // returns null as Object.prototype.__proto__ is null

Prototype chain is used for method lookup on objects. If a method does not exist on the object, javascript looks for method in its prototype. If not found in prototype, it goes deeper into prototype chain.

obj.toString() // calls Object.prototype.toString

In the above example, toString method does not exist on the obj directly. It gets found in obj’s prototype.

Set prototype of an object

Prototype of an object can be set using Object.create method which takes a prototype object.

const objProto = {
    getValue() {
        return this.value
    }
}
 
const obj = Object.create(objProto)
 
obj["value"] = 1
 
obj.getValue()
// 1

Class or function prototype

When we define a class, all the methods go to class’s prototype object. This allows javascript to reuse same methods for class instances.

We can find access prototype using prototype property on class.

class A {
    constructor() {
        this.value = 1
    }
 
    getValue() {
        return this.value
    }
}
 
a = A()
 
a.__proto__ === A.prototype

When the class is initialized using new, instance’s __proto__ gets class’s prototype object.

The same thing happens with function. When a function is called using new, prototype objects assigned to the instance’s __proto__.

const personProto = {
    getName () {
        return this.name
    }
}
 
function Person() {
    this.name = "john"
}
 
Object.assign(Person.prototype, personProto)
 
p = new Person()
 
p.getName()
// john

References

  1. https://en.wikipedia.org/wiki/Prototype-based_programming#Languages_supporting_prototype-based_programming
  2. https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Advanced_JavaScript_objects/Object_prototypes#setting_a_prototype