Searching Google for “Javascript Inheritance” returns some interesting but, IMO, also frustrating results such as Douglas Crockford’s various takes in Classical Inheritance in JavaScript or Kevin Lindsey’s approach, the former not really providing a clear answer while the latter relies on the convention of attaching a “superclass” property to your objects and effectively requires glueing your objects together for each instance you create.
Meanwhile libraries like prototype and MochKit have evolved their own conventions and strategies which you may or not may not appreciate. I’m grumpy in each case . prototype, despite having some very cool code in it, extends built-in Javascript types like Object which I don’t appreciate - makes me nervous about mixing in other Javascript libraries from other sources. Meanwhile looking at MochKit (which may be the best AJAX implementation out there, having made good reference to twisted) suffers from the kind of smartness summarized here, when it comes to it’s “Base”.
An Alternative
There is another way which probably gives you most of what you expect if you’re coming from a language like Java (ooops - can’t seem to stop it ;)). This is thanks to Troels Knak-Nielsen (author of indite - the realtime validating wysiwyg widget) who told me about it a long time ago on the JPSpan mailing list here.
function copyPrototype(descendant, parent) {
var sConstructor = parent.toString();
var aMatch = sConstructor.match( /\s*function (.*)\(/ );
if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
for (var m in parent.prototype) {
descendant.prototype[m] = parent.prototype[m];
}
};
Note: above code updated after initial post re this comment
At first glance, with that regex, it looks like a hack but if you allow it to sink in (which has taken me more than a year), you realise that it isn’t. It’s worth bearing in mind what Troels had to say about it;
First off - I fully understand and agree to the point of not extending language functionality. That said I think the point in relation to javascript and inheritance is often misunderstood. It is central to javascript that it is a “typeless objectoriented language”. This goes for ECMAscript3.0 all the same. Where people most often get it wrong is when they mistake prototypes for classes - they are not.
In a typed OO-language the objects code lies with the class - objects are just instances. In js, the code lies in the object. Therefore, the object is not tied to the prototype. It is ok in js to manipulate the prototype runtime, even after objects has been instantiated. Consider doing that with a typed language.
Anyway. I have been working a lot with js recently, and found that one-level inheritance is simple enough using prototypes, but further inheritance cause trouble. I guess you came to the same conclusion with JPSpan. My first googling on the subject turned up a lot of wierd hacks, that I don’t appreciate. I eventually invented a solution witch I use, and witch I’m very happy with. It may look as a hack, but it works so well, that I kind of forgive it for that.
To defend myself further I’ll point out that it’s not a language extension, if you just understand what it does. It’s merely a utility that extends a prototype - Which should not be confused with class inheritance (though the result is the same).
It’s easiest to see Troels point by trying it…
Basic Inheritance
The way you’d expect…
function Animal() {
this.species = "animal";
};
Animal.prototype.category = function() {
alert(this.species);
};
function Dog() {
// Call the parent constructor to setup
// the parent object properties...
this.Animal();
};
// Dog "inherits" from Animal
copyPrototype(Dog, Animal);
var d = new Dog();
d.category();
…and I get the alert “animal”
Another spin on that, this time without calling the parent constructor…
function Animal() {
this.species = "animal";
};
Animal.prototype.category = function() {
alert(this.species);
};
function Dog() {
// No call to parent constructor
this.species = "canine";
};
// Dog "inherits" from Animal
copyPrototype(Dog, Animal);
var d = new Dog();
d.category();
This time the alert reads “canine”.
Many generations
Often a problem with different approaches to Javascript inheritance, here’s how Troels approach deals with it;
function Animal() {
this.species = "animal";
};
Animal.prototype.category = function() {
alert(this.species);
};
function Dog() {
this.Animal();
this.species += ":dog";
};
// Dog "inherits" from Animal
copyPrototype(Dog, Animal);
function Poodle() {
this.Dog();
this.species += ":poodle";
};
// Poodle "inherits" from Dog
copyPrototype(Poodle, Dog);
var p = new Poodle();
p.category();
…alerts: “animal:dog:poodle”
Overriding Parent Methods
By default this approach simply replaces methods. That means you need to make sure you call copyPrototype before assigning any methods to the subclass prototype, otherwise the parent methods will override the child methods;
function Animal() {
this.species = "animal";
};
Animal.prototype.category = function() {
alert(this.species);
};
function Dog() {
this.Animal();
this.species += ":canine";
};
// Dog "inherits" from Animal
copyPrototype(Dog, Animal);
// Override parent method _after_ calling copyPrototype
Dog.prototype.category = function() {
alert(this.species.toUpperCase())
};
… displays “ANIMAL:CANINE”
It’s also possible, although slightly painful, to call a parent method which has been overridden, with help from apply. Modifying the above Dog.prototype.category method demonstrates this;
Dog.prototype.category = function() {
// Call overridden parent method...
Animal.prototype.category.apply(this);
alert(this.species.toUpperCase())
};
…which results in two alerts. If you needed to pass on method parameters, you’d need to pass the arguments array as the second argument to apply().
Mixins
MixIns (basically multiple inheritance) also works in a fairly predictable fashion;
function Animal() {
this.species = "animal";
};
Animal.prototype.category = function() {
alert(this.species);
};
function Quadruped() {};
Quadruped.prototype.run = function() {
alert('Running...');
}
function Dog() {
this.Animal();
this.species += ":canine";
};
// Dog "inherits" from Animal
copyPrototype(Dog, Animal);
// Dog "inherits" from Quadruped
copyPrototype(Dog, Quadruped);
var d = new Dog();
d.category();
d.run();
…two alerts: “animal:canine” and “Running…”
Cautions
Two particular warnings with this approach…
1. When you call copyPrototype matters, as already mentioned. In practice it means you’re best off calling it immediately after declaring a child constructor.
2. Do not declare a toString method for the parent class Function object as this may break the regular expression in copyPrototype. You can still modify a parent prototype without doing any harm though. In other words this will break copyPrototype;
Animal.toString = function() {
return "this is an animal";
}
But this is OK;
Animal.prototype.toString = function() {
return "this is an animal";
}
In Summary
Of all the approaches I’ve seen, to me this has become the most convincing - the best way to keep your code DRY without having to modify core Javascript types and introduce strange side effects. It’s also only 8 lines of code, so doesn’t cost much. Credit to Troels for sublime lateral thinking.
If you liked this blog, share the love:


January 17th, 2006 at 8:03 am
Peter Nederlof also had some thoughts on this, i think that’s even prettyer…
http://blogger.xs4all.nl/peterned/archive/2006/01/12/73948.aspx
January 17th, 2006 at 8:48 am
Not bad but have a few problems with Peter’s approach. That it’s modify Function may or may not be a problem (to me it’s a problem). More significant is it fires off parent constructors automatically - what if you don’t want the parent constructor called? Plus is doesn’t support Mixins.
Of course if you do want to extend Function, you could apply Troels approach in the same way as Peter and have the advantage of not having to reassign the Function object e.g.;
That way you still have control over the constructor and support for Mixins.
January 17th, 2006 at 10:08 am
I realized that if the constructor is empty, the regex will fail on ie (works fine at moz). Simply throwing a if (aMatch != null) { around the line which copies the constructor does the trick.
One more thing. Modifying the prototype actually changes already instantiated objects. Modyfying the parent prototype doesn’t. This might lead to some confusion.
January 17th, 2006 at 10:19 am
That’s one I hadn’t run into. Updated the example re your suggestion.
January 17th, 2006 at 3:08 pm
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Class-Based_vs._Prototype-Based_Languages
January 17th, 2006 at 3:28 pm
I think the use of the regex is a mistake. It is too fragile. It fails if you use anonymous functions like:
var Animal = function() { this.species = “animal”; }
Also, I’m not conviced it is that useful. With it, you
can call the superclass constructor as “this.Animal()”
Without it you’d use “Animal()” instead.
I’d suggest reserving a fixed property name, such as superclassConstructor, or just superclass, to hold the reference to the superclass constructor. Then you don’t need to rely on Function.prototype.toString() and regexp hackery to figure out the name of the superclass constructor. You just say:
descendant.prototype.superclass = parent;
January 17th, 2006 at 4:21 pm
Really want ecmascript v4..
Flashs’ actionscript 2.0 is based upon it, QuickTime has it.
But none of the browsers. :/
http://livedocs.macromedia.com/flash/8/main/00001870.html
January 17th, 2006 at 6:07 pm
There’s a much simpler way of doing inheritance if you don’t need multiple inheritance (mixins)–which, if you’re used to Java, you’ll instinctively avoid anyway. This approach is described in the link fabio posted above:
The only disadvantage I see here is that you’re not able to pass different arguments to the superclass’s constructor for each instance of the subclass you create. Am I missing something?
January 17th, 2006 at 7:44 pm
That’s a fair point. At the same time I would argue that using anonymous functions this way would only happen if you’re manipulating data / DOM on the fly. In other words this probably wouldn’t be a way to “publish” an API for other programmers to use and unlikely you’d be wanting to extend it (perhaps it might inherit from something else but I doubt vice versa).
There might also be issues with trying to extend build in classes - if I remember right IE doesn’t regard RegExp to be a class in the same way as Mozilla.
All that said and I know that regex looks very hacky but, under normal circumstances it’s going to do the right thing. Effectively it’s filling in for what typeof “fails” to do with user defined Objects.
Guess I’ve got a gut problem with that approach. Part of it is if you’re bringing different scripts together where people have used different conventions and perhaps another is simply too much thinking in terms of classic inheritance - having something so fundamental defined only be convention makes me nervous.
This may sound odd but there is some reason why I didn’t like that approach, after reading it long ago in Javascript: The Definitive Guide, but have forgotten the train of thought that brought me there.
It’s got something to do with this;
Poodle.prototype = new Dog();
alert(Poodle.prototype.constructor);
Here the constructor is the Animal constructor. With Troels approach you get to keep the Poodle constructor in the prototype. Quite why thats important though, I’ve long since forgotten ;) Perhaps it just seemed like a nasty side-effect. Will get back if I think of it.
January 17th, 2006 at 9:15 pm
Hmm yeah. It’s a little counter-intuitive (but then what about prototypes is intutive?), but I don’t see what problems this could cause either.
In particular, why ask for
Poodle.prototype.constructorwhen you can just ask forPoodle? If your goal is to be able to access the constructor from an instance, well that’s a different story. But like yourself, I can’t think of a situation where you would need to.January 18th, 2006 at 7:58 am
Still pondering and so far the only real reason I can think of is when you need to work out what user defined class an instance was created from like;
var MsTibbles = new Poodle(); // ... later if ( MsTibbles.constructor == Poodle ) {That’s something you need in the absence of “instanceof” but that may no longer be an issue these days - I don’t know the history of various ECMAScript implementations and when instanceof was supported, but it’s in Firefox 1.5 and seems of have been implemented in “Javascript 1.4″.
Otherwise nice link here discussing some of this.
Anyway - it’s now bugging me ;)
January 18th, 2006 at 5:28 pm
HarryF wrote:
Actually, anonymous functions are probably even more common in production library code that is published. That is because it is good practice to put it in a namespace. For example:
var com = {}; com.davidflanagan = {}; com.davidflanagan.Animal = function() { ... }This kind of namespacing is standard with module libraries such as JSAN and (I think) Dojo. Your code won’t interoperate with code from those repositories.
January 19th, 2006 at 5:10 am
That’s a very good point that I hadn’t considered. I guess it would be possible to support that in a different implementation, where you pass a string identifying the parent rather than a reference to the function object - something like;
But that’s starting to look very hacky and there’s probably more cases there I haven’t considered.
Anyway - thanks for pointing that out.
January 19th, 2006 at 7:30 am
Can I just mention that all of the code samples in this article are disappearing as soon as the page is loaded when I view this in IE 6.0 on WinXP Pro?
Not my first choice of browser or OS, but this is a corporate build!
January 19th, 2006 at 7:54 am
On the contrary, I recall reading only a few days ago (can’t remember where) that anonymous functions were a good way of simulating Java’s ‘Private’ access modifier, since it prevented third parties calling such functions easily.
On a seperate note, I can’t see why you would go to all of the bother of setting up inheritance like this, then choose to not use it occassionally, as was suggested. A poodle is always a dog, and an animal, so if this feature is needed it suggests to me that the object model has been badly designed.
January 19th, 2006 at 6:28 pm
In general, I don’t really trust anything that relies on string manipulation and string manipulation isn’t known to be extremely fast (though in this case, that code doesn’t actually run too much).
I think Kevin Yank’s implementation is fine and the .constructor problem is the exact one addressed by KevLinDev’s article.
I think this implementation is interesting because it’s conceptually better because when inheriting from objects, it just copies their “.prototype” properties over rather than assign their prototype to a new object (Dog.prototype = new Animal()). Hence, as Kevin points out, you can call a constructor with parameters. I would argue that it offers other benefits b/c the descendant’s methods don’t point to a random superclass object but instead do the method/property lookup correctly via the proto-chain. However, in order to do this, you have to loop through every property on the superclass’s .prototype object, which could be a little slow (but it’s only done once so not a big deal).
January 19th, 2006 at 6:43 pm
David Flanagan makes a very relevant point.
A client asked me to whisk some thick client dhtml together in a hurry (basically as netvibes.com clone), so I took a deeper look at some of the emerging javascript frameworks.
The copyPrototype as shown by harry doesn’t work with name.space.foo = function … style, which is rather annoying.
Even if it worked, the constructor contains dots in it’s name, so you can’t really create a function by the same name.
Anyway - As harry describes, calling overridden methods is possible through the magic of a little known construct called apply. This same construct can be used to call parent constructors. It may seem a bit clunky, but if you ever used PHP4 to write OO code, you’ll recognize that you are essentially calling a static method from within an object instance - works the same way.
To conclude, the following works :
Once you got used to the .apply(this, arguments) it’s rather harmless, and there is no need for wierd hacks and extending the build-in objects’ prototype.
PS: omnicity - yes, very annoyingly this page is broken in IE …
January 19th, 2006 at 8:38 pm
Thanks for reporting this! We’re on it…
January 24th, 2006 at 1:37 am
Is it just me or does it seem that the comments are leading straight back to crawford?
Funny that I could never really grasp crawford’s approach until reading through this thread; copying, testing and renaming the examples (to ‘inherits’ no less).. only to re-read crawford to find this:
January 27th, 2006 at 5:11 am
[…] En me baladant, je suis tombé sur ce très bon article qui présente différents héritages en Javascript et en détaille un en particulier. Personnellement, je préfère les méthodes Crockford, mais cette démarche doit aussi avoir du bon. En tout cas, elle démontre encore une fois la puissance du Javascript, que je trouve décidément très proche du Ruby. […]
January 28th, 2006 at 3:02 pm
MochiKit doesn’t have an approach to inheritance. The *only* inheritance in MochiKit is to create the various Error constructors so that “instanceof Error” can be used to detect one (useful for Deferreds), and that does inheritance in the idiomatic JavaScript way.
Everything else in MochiKit uses more functional patterns. In my experience with languages like Python is that you really just don’t need inheritance for much, and that’s four times as true in JavaScript.
I’m not entirely sure what you mean by the 60kloc reference. MochiKit is less than 8kloc in total with comments, and Base is less than 1.5. The functionality in Base is pretty shallow — it’s mostly the minimum required functionality in order to make the rest of MochiKit possible. If you were to have your way, what would be there? Or more importantly, what *wouldn’t*?
MochiKit originally was going to have an inheritance method, but it turned out to be YAGNI. I wrote a bunch of code that make single inheritance work (while maintaining the functionality of instanceof), but I just didn’t need it at all in any production or library code.. so I tossed it. Someone else was interested in it, so it lives on here though:
http://openjsan.org/doc/r/rk/rkinyon/Class/0.05/lib/Class.html
February 8th, 2006 at 2:19 am
I recently had an idea about this and was wondering what your thoughts were. The implementation is as follows:
I like it because I can build a nice prototype chain without calling the SuperClass constructor JUST to get the inheritance (gets messy if the constructor actually does something or requires args). It also gets around the obj.constructor problem.
This doesn’t allow (directly) for multiple inheritance, but it could also be used in conjunction with a class augmentation/copy approach (and I tend to shy away from multiple inheritance anyway).
I’ve posted the idea on my blog at http://www.itsalleasy.com/2006/02/05/prototype-chain/
March 6th, 2006 at 6:01 pm
[…] Read the article SitePoint Blogs » Javascript Inheritance […]
March 9th, 2006 at 1:44 pm
I’ve come up with a way of doing inheritance that suites my needs. I created a helper function Class() that builds the class based on objects passed in. It’s super simple to use and the code is clean. I’ve posted code and details on my blog:
http://ambientreality.blogspot.com/2006/03/javascript-inheritance.html
Feedback is welcome.
March 18th, 2006 at 4:10 am
I beleive inheritance is most easily acheived using the following:
Any comments to johnny_barry@hotmail.com
The ideas above could be packaged into functions but I think it is better to get use to how ecmascript works. Function.prototype.call() and Function.prototype.apply() are great functions!
March 23rd, 2006 at 4:48 pm
[…] I want to achieve the above without resorting to global functions to build prototype chains […]
March 24th, 2006 at 8:56 pm
[…] I want to achieve the above without resorting to global functions to build prototype chains […]
April 1st, 2006 at 3:25 pm
[…] If you’re like me, however, you’re still rather troubled by prototype’s claim of “class-driven development” in Javascript. In fact, you’re probably a little fuzzy on the differences between object-oriented and prototype-based languages (hey, is that why they called it prototype?), and, if you’ve investigated them, you find approaches to enabling classical object-oriented development in Javascript rather unintuitive. (See here, here, and here, all good stuff, but rather painful to use). […]
June 18th, 2006 at 1:59 pm
[…] I want to achieve the above without resorting to global functions to build prototype chains […]
June 22nd, 2006 at 4:49 pm
[…] I want to achieve the above without resorting to global functions to build prototype chains […]
July 18th, 2006 at 4:38 pm
Everyone, the above code of
copyPrototype()in the article will NOT work in Internet Explorer (6.0) but works just fine in Firefox up to 1.5.0.4 in this following case:The reason is that the regexp in
copyPrototypeused to match the parent’s constructor will also match the space after (and before) the constructor’s name. Hence instead of grabbing “Animal” only, the pattern will also grab “Animal ” instead. Firefox, however, resolve this just fine. IE, on the other hand, will give out a nasty and almost unidentifiable result in the callthis.Animal()in the Dog’s constructor. This bug took me almost 2 days to slowly work through and discover.So here is the new fix snippet of
copyPrototype()that will work with any type of function declarations:What I have added here is
aMatch[1].replace(/^\s*|\s*$/g,"")to trim the space before and after function name before the assignment. This updated code has proved to work well in my test cases.Cheers!
Alex Le at http://www.alexle.net
August 4th, 2006 at 2:00 am
I’ve blogged about an alternate approach which seems considerably more elegant to me - I’d be interested to hear what you think!
July 18th, 2007 at 7:10 pm
Hi,
The single inheritance example below doesn’t need copyPrototype.
It works fine.
And is possible to call the base class method which has been overridden.
July 18th, 2007 at 7:25 pm
Hi,
Your code would look like this.
It’s simple and good enough for my needs.
As said, I’m happy that it doesn’t need copyPrototype and is possible to call the base class method which has been overridden.
April 16th, 2008 at 10:46 pm
function inherit(descendant, parent) {
var sConstructor = parent.toString();
var aMatch = sConstructor.match( /\s*function (.*)\(/ );
if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
for (var m in parent.prototype) {
// MY HUMBLE ADDITION
if (typeof(parent.prototype[m]) == ‘function’) {
descendant.prototype[aMatch[1]+’_'+m] = parent.prototype[m];
}
descendant.prototype[m] = parent.prototype[m];
}
}
my humble addition allows parent methods to be called without using “apply”.
if B extends A as in Mr. Fuecks examples, and “obj” is an instance of A, and “category” a virtual function, class A’s version can be invoked on obj as “obj.A_category()” similar to the c++ syntax “obj->A::category()”
May 12th, 2008 at 7:01 pm
Hi,
I have tried an different techniques related to JavaScript inheritance subject.
The code and the explanation are to long to post them here so if anyone is interested to take a look over it you can find it at http://www.dotnetcaffe.net under JavaScript category. Fell free to criticize the code in any way you want…just don’t flame :).