As a prototype-based language, JavaScript has a less apparent way of defining object hierarchies. But of course it’s doable.

Prototype

  • What is a prototype?

    A prototype is an object which other objects reference by their [[Prototype]] property.

    The [[Prototype]] property is typically implemented by __proto__:

    var a = {};
    a.__proto__;
    
  • Which objects have a prototype?

    By default, all objects (except one) have a prototype. Explained next.

  • What is a prototype chain?

    Assume by default. Since every object (except one) has a prototype, an object’s prototype also has a prototype, an object’s prototype’s prototype also has a prototype, etc.:

    a.__proto__;
    a.__proto__.__proto__;
    a.__proto__.__proto__.__proto__;
    ...
    

    This forms a prototype chain.

  • What’s the only one object that doesn’t have a prototype?

    It’s the default object sitting at the end of all prototype chains:

    a.__proto__.....__proto__.__proto__;
    > null
    
  • Why is prototype chain useful?

    An object inherits properties from objects on its prototype chain, in order:

    var a = { 'name': 'myname' };
    var b = new Object();
    b.__proto__ = a;
    var c = new Object();
    c.__proto__ = b;
    c.name;
    > 'myname'
    
    b.name = 'mynewname';
    c.name;
    > 'mynewname'
    

    The counterpart of prototype in a class-based language is class.

  • Is there a standard accessor to access an object’s prototype?

    ECMAScript 5 introduces Object.getPrototypeOf() to get an object’s prototype:

    var a = {};
    var b = Object.getPrototypeOf(a);
    b === a.__proto__;
    > true
    

    However, it’s only a getter and you cannot use it to set an object’s prototype.

  • How can I create an object with a specified prototype?

    Say we want to create an object b which has prototype a.

    • Since ECMAScript 5:

      var b = Object.create(a);
      
    • Before ECMAScript 5:

      function F() {};
      F.prototype = a;
      var b = new F();
      

Function

  • Does every function has a prototype?

    Yes. Every object (except one) has a prototype and a function is an object (and is not the exception).

  • A function has a prototype field. What’s that?

    It’s the prototype of all objects created by this function when it’s used as a constructor:

    F = function() {};
    f = new F();
    f.__proto__ === F.prototype;
    > true
    

    Don’t mess it up with the prototype of the function itself:

    f.__proto__ == F.__proto__
    > false
    

    The prototype field only exists in function objects.

  • What’s does a freshly created prototype look like?

    An object with a constructor field, which is the function that created this object.

    F.prototype.constructor === F;
    > true
    

Inheritance

  • How to implement inheritance in JavaScript?

    Say we want to let Extend extend Base:

    Base = function () {
        ...                 // init Base members
    }
    Extend = function() {
        Base.call(this);    // init Base members
        ...                 // init Extend members
    }
    Extend.prototype = Object.create(Base.prototype);   // set Extend objects' prototype
    Extend.prototype.constructor = Extend;              // amend Extend object's prototype
    

References

  1. Understanding JavaScript Prototypes.
  2. ECMA-262-3 in detail. Chapter 7.2. OOP: ECMAScript implementation.