Skip to content

Instantly share code, notes, and snippets.

@gflarity
Created February 25, 2011 13:36
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 gflarity/843783 to your computer and use it in GitHub Desktop.
Save gflarity/843783 to your computer and use it in GitHub Desktop.
Understanding Inheritance In JavaScript
This is a rough outline for an article
In this article I will present the JavaScript inerhitence model in a concise and I hope easy to understand manner. The intended audience consists of developers with some previous experience with dynamically typed languages. It is my opinion that any difficulty associated with understanding the JavaScript inheritance model can be attributed to the difficulty teaching recursive definitions in general. It's sometimes hard to know where to start, when your definition is circular.
That said, let's boil JavaScript inheritance down into 5 key points:
1) In JavaScript, everything is an 'object' and all variables simply hold references to them. The other 'primitive' or basic types (of objects) are functions, booleans, strings, numbers and arrays.
2) Objects are collections of properties keyed by a reference. Most often, references to string objects are used as keys as they are immutable. This means that if foo and bar reference string types which contain the same data they are in fact the same object. This essentially makes Objects equivalent to hashes or dictionaries in other languages.
3) In JavaScript functions are special objects. Not only can they be 'called', they have a special 'prototype' property which holds an object that can be accessed and modified. When a function is used as a constructor with the 'new' key word, the resulting object that is created will *dynamically* inherit from the object referenced by the constructor function's 'prototype' property.
Example:
> Constructor = function() { };
> Constructor.prototype.name = 'alpha';
> Constructor.prototype.say_name = function() { console.log("my name is: " + this.name) };
> object = new Constructor();
> object.say_name();
3) Upon initial definition, the prototype property of every new function can be thought of like this:
func = function() {}
func.prototype = { 'constructor': func };
That is, the value referenced by func.prototype is an object contains a reference to func itself. This recursive definition is a bit eye-crossing but actually very beautiful in that way that only recursion can be.
4) Here's where the recursive definitions start to get difficult to visualize. In JavaScript, every object (including functions) dynamically inherit from the special 'Object.prototype' object. In other words, 'Object' is THE constructor function of ALL objects in the JavaScript universe. The corollary being that Object.prototype.constructor == Object.
Try it:
> Object.prototype.constructor == Object
true
These 4 points form the foundation of inheritance in JavaScript. Let's make use what we've learned:
Corollary 1:
Object types, or 'classes' can be (and generally are) referred to by their contructor function. Examples: Object, Function, String, Boolean, Array etc.
Corollary 2:
If you want to add a method to every object in the javascript universe (even after it is constructed!), mess with Object.prototype.
Example:
> Object.prototype.foo = 'bar'
> func = function() {}
> func.foo
"bar"
> Object.prototype.foo = 'baz'
> func.foo
"baz"
Corollary 3:
There's no such thing as multiple inheritance in JavaScript. That is class 'Foo' can not inherit from both 'String' and 'Array' directly. Though, you can use some clever tricks to hack multiple inheritance into the language. For examples, see http://www.amirharel.com/2010/06/11/implementing-multiple-inheritance-in-javascript and http://code.google.com/p/joose-js/.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment