JavaScript Prototypes and Inheritance June 10th, 2014

Objects have a built-in attribute called prototype who’s value is a pointer to another object, and can be declared when creating a new object with Object.create(myPrototypeReference). If an object is created using the convenience of an object literal var newObject = {property: ‘value‘} then the prototype is defaulted to Object.prototype.

Overview

  • Objects are pairs of keys and values called properties (in Ruby, this structure is called a Hash; in Python, it’s called a dictionary)
  • Properties can be enumerable, configurable, and writable
  • Objects have a built-in attribute called prototype who’s value is a pointer to another object
    • Specify an object’s prototype by using Object.create(prototype) when creating the new object
    • If you don’t need a prototype then you can use the convenience of the object literal syntax instead … var newObject = {property: ‘value‘} … which always set the newly created object’s prototype to an object located at Object.prototype
  • You can look up an object’s prototype by using Object.getPrototypeOf(object)
  • Define new properties with Object.defineProperty(object, ‘newKey’, {value:‘New Key Value’, writable:true, enumerable:true, configurable:true})
    • Since creating a new writable, configurable, enumerable property is pretty common, JavaScript makes it easy to do so using assignment syntax instead … object.newKey = ‘newValue’
  • Prototypes can be used to inherit functionality
  • If you try to look up a key on an object and it is not found, JavaScript will look for it in the prototype. It will follow the “prototype chain” until it sees a null value. In that case, it returns undefined.

Prototypal Inheritance Analogy

var defaults = {
    zero: 0,
    one: 1
};

var myOptions = Object.create(defaults);
var yourOptions = Object.create(defaults);

// When I want to change *just* my options
myOptions.zero = 1000;

// When you wanna change yours
yourOptions.one = 42;

// When we wanna change the **defaults** even after we've got our options
// even **AFTER** we've already created our instances
defaults.two = 2;

myOptions.two; // 2
yourOptions.two; // 2

Resources