Our volunteers haven't translated this article into עברית yet. Join us and help get the job done!
You can also read the article in English (US).

JavaScript is a bit confusing for developers experienced in class-based languages (like Java or C++), as it is dynamic and does not provide a class implementation per se (the class keyword is introduced in ES2015, but is syntactical sugar, JavaScript remains prototype-based).

When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype, and acts as the final link in this prototype chain.

Nearly all objects in JavaScript are instances of Object which sits on the top of a prototype chain.

While this confusion is often considered to be one of JavaScript's weaknesses, the prototypal inheritance model itself is, in fact, more powerful than the classic model. It is, for example, fairly trivial to build a classic model on top of a prototypal model.

Inheritance with the prototype chain

Inheriting properties

JavaScript objects are dynamic "bags" of properties (referred to as own properties). JavaScript objects have a link to a prototype object. When trying to access a property of an object, the property will not only be sought on the object but on the prototype of the object, the prototype of the prototype, and so on until either a property with a matching name is found or the end of the prototype chain is reached.

Following the ECMAScript standard, the notation someObject.[[Prototype]] is used to designate the prototype of someObject. Since ECMAScript 2015, the [[Prototype]] is accessed using the accessors Object.getPrototypeOf() and Object.setPrototypeOf(). This is equivalent to the JavaScript property __proto__ which is non-standard but de-facto implemented by many browsers.

It should not be confused with the func.prototype property of functions, which instead specifies the [[Prototype]] to be assigned to all instances of objects created by the given function when used as a constructor. The Object.prototype property represents the Object prototype object.

Here is what happens when trying to access a property:

// Let's create an object o from function f with its own properties a and b:
let f = function () {
   this.a = 1;
   this.b = 2;
let o = new f(); // {a: 1, b: 2}

// add properties in f function's prototype
f.prototype.b = 3;
f.prototype.c = 4;

// do not set the prototype f.prototype = {b:3,c:4}; this will break the prototype chain
// o.[[Prototype]] has properties b and c.
// o.[[Prototype]].[[Prototype]] is Object.prototype.
// Finally, o.[[Prototype]].[[Prototype]].[[Prototype]] is null.
// This is the end of the prototype chain, as null,
// by definition, has no [[Prototype]].
// Thus, the full prototype chain looks like:
// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null

console.log(o.a); // 1
// Is there an 'a' own property on o? Yes, and its value is 1.

console.log(o.b); // 2
// Is there a 'b' own property on o? Yes, and its value is 2.
// The prototype also has a 'b' property, but it's not visited. 
// This is called "property shadowing."

console.log(o.c); // 4
// Is there a 'c' own property on o? No, check its prototype.
// Is there a 'c' own property on o.[[Prototype]]? Yes, its value is 4.

console.log(o.d); // undefined
// Is there a 'd' own property on o? No, check its prototype.
// Is there a 'd' own property on o.[[Prototype]]? No, check its prototype.
// o.[[Prototype]].[[Prototype]] is null, stop searching,
// no property found, return undefined.

Code Link

Setting a property to an object creates an own property. The only exception to the getting and setting behavior rules is when there is an inherited property with a getter or a setter.

Inheriting "methods"

JavaScript does not have "methods" in the form that class-based languages define them. In JavaScript, any function can be added to an object in the form of a property. An inherited function acts just as any other property, including property shadowing as shown above (in this case, a form of method overriding).

When an inherited function is executed, the value of this points to the inheriting object, not to the prototype object where the function is an own property.

var o = {
  a: 2,
  m: function() {
    return this.a + 1;

console.log(o.m()); // 3
// When calling o.m in this case, 'this' refers to o

var p = Object.create(o);
// p is an object that inherits from o

p.a = 4; // creates a property 'a' on p
console.log(p.m()); // 5
// when p.m is called, 'this' refers to p.
// So when p inherits the function m of o, 
// 'this.a' means p.a, the property 'a' of p

Different ways to create objects and the resulting prototype chain

Objects created with syntax constructs

var o = {a: 1};

// The newly created object o has Object.prototype as its [[Prototype]]
// o has no own property named 'hasOwnProperty'
// hasOwnProperty is an own property of Object.prototype. 
// So o inherits hasOwnProperty from Object.prototype
// Object.prototype has null as its prototype.
// o ---> Object.prototype ---> null

var b = ['yo', 'whadup', '?'];

// Arrays inherit from Array.prototype 
// (which has methods indexOf, forEach, etc.)
// The prototype chain looks like:
// b ---> Array.prototype ---> Object.prototype ---> null

function f() {
  return 2;

// Functions inherit from Function.prototype 
// (which has methods call, bind, etc.)
// f ---> Function.prototype ---> Object.prototype ---> null

With a constructor

A "constructor" in JavaScript is "just" a function that happens to be called with the new operator.

function Graph() {
  this.vertices = [];
  this.edges = [];

Graph.prototype = {
  addVertex: function(v) {

var g = new Graph();
// g is an object with own properties 'vertices' and 'edges'.
// g.[[Prototype]] is the value of Graph.prototype when new Graph() is executed.

With Object.create

ECMAScript 5 introduced a new method: Object.create(). Calling this method creates a new object. The prototype of this object is the first argument of the function:

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
// undefined, because d doesn't inherit from Object.prototype

With the class keyword

ECMAScript 2015 introduced a new set of keywords implementing classes. The new keywords include class, constructor, static, extends, and super.

'use strict';

class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;

class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  get area() {
    return this.height * this.width;
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;

var square = new Square(2);


The lookup time for properties that are high up on the prototype chain can have a negative impact on the performance, and this may be significant in the code where performance is critical. Additionally, trying to access nonexistent properties will always traverse the full prototype chain.

Also, when iterating over the properties of an object, every enumerable property that is on the prototype chain will be enumerated. To check whether an object has a property defined on itself and not somewhere on its prototype chain, it is necessary to use the hasOwnProperty method which all objects inherit from Object.prototype. To give you a concrete example, let's take the above graph example code to illustrate it:

// true

// false

// false

// true

hasOwnProperty is the only thing in JavaScript which deals with properties and does not traverse the prototype chain.

Note: It is not enough to check whether a property is undefined. The property might very well exist, but its value just happens to be set to undefined.

Bad practice: Extension of native prototypes

One misfeature that is often used is to extend Object.prototype or one of the other built-in prototypes.

This technique is called monkey patching and breaks encapsulation. While used by popular frameworks such as Prototype.js, there is still no good reason for cluttering built-in types with additional non-standard functionality.

The only good reason for extending a built-in prototype is to backport the features of newer JavaScript engines, like Array.forEach.


B shall inherit from A:

function A(a) {
  this.varA = a;

// What is the purpose of including varA in the prototype when A.prototype.varA will always be shadowed by
// this.varA, given the definition of function A above?
A.prototype = {
  varA: null,  // Shouldn't we strike varA from the prototype as doing nothing?
      // perhaps intended as an optimization to allocate space in hidden classes?
      // https://developers.google.com/speed/articles/optimizing-javascript#Initializing-instance-variables
      // would be valid if varA wasn't being initialized uniquely for each instance
  doSomething: function() {
    // ...

function B(a, b) {
  A.call(this, a);
  this.varB = b;
B.prototype = Object.create(A.prototype, {
  varB: {
    value: null, 
    enumerable: true, 
    configurable: true, 
    writable: true 
  doSomething: { 
    value: function() { // override
      A.prototype.doSomething.apply(this, arguments); // call super
      // ...
    enumerable: true,
    configurable: true, 
    writable: true
B.prototype.constructor = B;

var b = new B();

The important parts are:

  • Types are defined in .prototype.
  • You use Object.create() to inherit.

prototype and Object.getPrototypeOf

JavaScript is a bit confusing for developers coming from Java or C++, as it's all dynamic, all runtime, and it has no classes at all. It's all just instances (objects). Even the "classes" we simulate are just a function object.

You probably already noticed that our function A has a special property called prototype. This special property works with the JavaScript new operator. The reference to the prototype object is copied to the internal [[Prototype]] property of the new instance. For example, when you do var a1 = new A(), JavaScript (after creating the object in memory and before running function A() with this defined to it) sets a1.[[Prototype]] = A.prototype. When you then access properties of the instance, JavaScript first checks whether they exist on that object directly, and if not, it looks in [[Prototype]]. This means that all the stuff you define in prototype is effectively shared by all instances, and you can even later change parts of prototype and have the changes appear in all existing instances, if you wanted to.

If, in the example above, you do var a1 = new A(); var a2 = new A(); then a1.doSomething would actually refer to Object.getPrototypeOf(a1).doSomething, which is the same as the A.prototype.doSomething you defined, i.e. Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething.

In short, prototype is for types, while Object.getPrototypeOf() is the same for instances.

[[Prototype]] is looked at recursively, i.e. a1.doSomething, Object.getPrototypeOf(a1).doSomething, Object.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething etc., until it's found or Object.getPrototypeOf returns null.

So, when you call

var o = new Foo();

JavaScript actually just does

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

(or something like that) and when you later do


it checks whether o has a property someProp. If not, it checks Object.getPrototypeOf(o).someProp, and if that doesn't exist it checks Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp, and so on.

Types of prototypal inheritance

There are three types of prototypal inheritance: delegation inheritance, concatenative inheritance and functional inheritance.

Delegation inheritance

A delegate prototype is an object that serves as a base for another object. When you inherit from a delegate prototype, the new object gets a reference to the prototype.

When you try to access a property on the new object, it checks the object’s own properties first. If it doesn’t find it there, it checks the [[Prototype]], and so on up the prototype chain until it gets back to Object.prototype, which is the root delegate for most objects.

Method delegation can preserve memory resources because you only need one copy of each method to be shared by all instances.

There are several ways to set up the relationship in JavaScript. The one you’re likely to see in ES6 goes something like this:

class Greeter {
  constructor (name) {
    this.name = name || 'John Doe';
  hello () {
    return `Hello, my name is ${ this.name }`;

const george = new Greeter('George');
const msg = george.hello();
console.log(msg); // Hello, my name is George

You can avoid property delegation by setting the prototype to null using Object.create(null).

One major drawback to delegation is that it’s not very good for storing state. If you try to store state as objects or arrays, mutating any member of the object or array will mutate the member for every instance that shares the prototype.

In order to preserve instance safety, you need to make a copy of the state for each object.

Concatenative inheritance

Concatenative inheritance is the process of copying the properties from one object to another, without retaining a reference between the two objects.

It relies on JavaScript’s dynamic object extension feature. Cloning is a great way to store default state for objects: This process is commonly achieved using Object.assign(). Prior to ES6, it was common to use similar .extend() methods from Lodash, Underscore, or jQuery.

const proto = {
  hello: function hello() {
    return `Hello, my name is ${ this.name }`;

const george = Object.assign({}, proto, {name: 'George'});
const msg = george.hello();
console.log(msg); // Hello, my name is George

Concatenative inheritance is very powerful, but it gets even better when you combine it with closures.

Functional inheritance

The Name Functional Inheritance was coined by Douglas Crockford in “JavaScript: The Good Parts”. Functional inheritance makes use of a factory function, and then tacks on new properties using concatenative inheritance.

Functions created for the purpose of extending existing objects are commonly referred to as functional mixins.The primary advantage of using functions for extension is that it allows you to use the function closure to encapsulate private data.

In other words, you can enforce private state.

It’s a bit awkward to hang the attributes on a public property where a user could set or get them without calling the proper methods. What we really want to do is hide the attributes in a private closure. It looks something like this:

// import Events from 'eventemitter3';

const rawMixin = function () {
  const attrs = {};
  return Object.assign(this, {
    set (name, value) {
      attrs[name] = value;
      this.emit('change', {
        prop: name,
        value: value
    get (name) {
      return attrs[name];
  }, Events.prototype);

const mixinModel = (target) => rawMixin.call(target);
const george = { name: 'george' };
const model = mixinModel(george);
model.on('change', data => console.log(data));
model.set('name', 'Sam');
  prop: 'name',
  value: 'Sam'

By moving attrs from a public property to a private identifier, we remove all trace of it from the public API. // The only way to use it now is via the privileged methods. Privileged methods are any methods defined within the closure’s function scope, which gives them access to the private data.

Note in the example above, we have the mixinModel() wrapper around the actual functional mixin, rawMixin().  The reason we need that is because we need to set the value of this inside the function, which we do with Function.prototype.call(). We could skip the wrapper and let callers do that instead, but that would be obnoxious.

In 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.