Javascript Prototypal Inheritance

A quick reference for yours truly :)

JavaScript is prototype-based, even when taking ES6 into account. ES6 adds Class keyword but this is syntactic sugar on top of the prototype system.

Objects are the only construct for inheritance. Each object has a link to another object, it's prototype. The prototype chain is a powerful feature of Javascript, though it is sometimes lamented. This prototype chaining is more powerful than its classical counterpart.

var o = {a: 1};
// o ---> Object.prototype ---> null
var a = ["yo", "whadup", "?"];
// a ---> Array.prototype ---> Object.prototype ---> null
function f(){ return 2; }
// f ---> Function.prototype ---> Object.prototype ---> null

Constructor

function MyObject() {
  this.values = [];
}
MyObject.prototype = {
  addValues: function(v){
    this.values.push(v);
  }
};
var g = new MyObject();
// g is an object with own properties 'values'.
// g.[[Prototype]] is the value of MyObject.prototype when new MyObject() is executed.

Object.create

var a = {a: 1}; 
// a ---> Object.prototype ---> null

var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (inherited)

var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null

var d = Object.create(null);
// d ---> null
console.log(d.hasOwnProperty); 
// undefined, because d doesn't inherit from Object.prototype

When doing:

var o = new Foo();

Javascript does:

var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);

Misc

  • Say no to 'Monkey Patching', extending Object.prototype or extending library prototypes
  • Performance is an issue with deep prototype chains
  • Properties defined on prototypes are available to all instances of that object
  • When looking for a property the object is checked first then the objects prototype

Key Point

Prefer Prototypal Inheritance to Classical Inheritance

Resources

Above is paraphrasing from MDN.