Skip to content

Instantly share code, notes, and snippets.

@bruceharris
Created December 12, 2012 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bruceharris/4264796 to your computer and use it in GitHub Desktop.
Save bruceharris/4264796 to your computer and use it in GitHub Desktop.
JavaScript's Prototype System

JavaScript's Prototype System

When I ask interview candidates to explain what prototypes mean in JavaScript, the response is often something like this

Here's my attempt to explain it succinctly.

I think it's important to draw the distinction between 2 related concepts: the prototype property of functions, and the prototype of an object

The prototype property of functions

Every function in JavaScript has a prototype property (which is an object). When a new object is created by invoking a function using the new operator, e.g. invoking the function as a constructor, the resulting object has a hidden link to that prototype object. The prototype object to which the new object is linked can be described as the object's prototype.

An object's prototype

Every object in JavaScript has a hidden link to the prototype property of the constructor function that created it.

Object literals (not created with a constructor function) have a hidden link to Object.prototype, e.g. the protoype property of Object, which can be thought of as the mother of all constructor functions.

Property resolution

When looking up a property in an object, if the property is not found in the object itself, the JavaScript engine will then look in the object's prototype. Since the prototype is itself an object, the same rules apply, in that if a property is not found on the prototype, it will be looked up on its prototype. This chain continues until Object.prototype is reached.

For example

function Dog(name) {
  if (name) this.name = name;
}

// add properties to Dog's prototype property
Dog.prototype.bark = function() {
  return "woof";
};
Dog.prototype.name = 'Fido'; // default name

If we invoke Dog as a constructor with no name argument

var d = new Dog;          // d now has a hidden link to Dog.prototype
console.log(d.name);      // prints 'Fido' - d doesn't have a name property but it is found on Dog.prototype
console.log(d.bark());    // prints 'woof' - d doesn't have a bark property but it is found on Dog.prototype

If we invoke Dog as a constructor with a name argument

var d = new Dog('Spot');  // d now has a hidden link to Dog.prototype
console.log(d.name);      // prints 'Spot' - d has its own name property
console.log(d.bark());    // prints 'woof' - d doesn't have a bark property but it is found on Dog.prototype
delete d.name;            // d no longer has its own name property
console.log(d.name);      // prints 'Fido' - d "shines through" from Dog.prototype

Going up the chain...

// d doesn't have a toString property, and neither does Dog.prototype
// but toString is found on Object.prototype
console.log(d.toString()); // prints "[object Object]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment