JavaScript inheritance - how and why

Published on Monday, October 6th, 2008

Currently I’m working a fair bit with JavaScript and teaching different ways to use it, and what I want to talk to you about is if and how you use inheritance in JavaScript.

The prototype way

The way inheritance works in JavaScript is that it is prototype-, instead of class-based. For instance, take a look at this:

function Being () {
	this.living = true;
}
Being.prototype.breathes = function () {
	return true;
};

An object which inherits Being:

Robert.prototype = new Being;
function Robert () {
	this.blogs = true;
}
Robert.prototype.getsBored = function () {
	return "You betcha";
};

So, basically, if we create a new instance of the Robert object and call some of its methods, the result would be:

// Create an instance of the Robert object
var me = new Robert();

/*
	Returns "You betcha" as it's a method
	belonging to the Robert object
*/
me.getsBored();

/*
	Returns true. Since the Robert object
	doesn't have a breathes method of
	its own, it goes back in the
	prototype chain to its parent
	object, Being, and finds the
	method there
*/
me.breathes();

Calling a parent’s method

If you want to call a super method of the method currently being executed, i.e. if the same method also exists on the parent object, this is how it would have been done the prototype way:

Robert.prototype.getsBored = function () {
	/*
		Basically, you need to know the name of
		the object and the method name as well.
		Then call it in context
	*/
	Being.prototype.getsBored.call(this);
	return "You betcha";
};

Just to point it out, you could also write: this.constructor.prototype.getsBored.call(this);. The reason for this is that this.constructor points to the main constructor of the object, hence the Being object in this case.

Read more about prototype inheritance

For a more thorough explanation, read about Prototypes and Inheritance - JavaScript: The Definitive Guide.

People mimicking class-based inheritance

A lot of developers, however, come from a class-based inheritance world and either prefer that syntax or just refrain from wanting to use different syntaxes/approaches for different languages. A result of this has been a number of implementations of a more class-based nature in JavaScript, of which these are some of the more well-known ones:

I won’t dig into details into these, but the above code would look something like this with John Resig’s implementation:

var Being = Class.extend({
	living : true,
	breathes : function () {
		return true;
	}
});

var Robert = Being.extend({
	blogs : true,
	getsBored : function () {
		return "You betcha";
	}
});

var me = new Robert();
me.getsBored(); // Returns "You betcha"
me.breathes(); // Returns true

Calling a parent’s method, super-style

If both the Being object and the Robert object were to have a getsBored method, you’d have the option to call the one belonging to the Being object in a very easy manner:

var Robert = Being.extend({
	blogs : true,
	getsBored : function () {
		// This is the syntax to call a super method
		this._super();
		return "You betcha";
	}
});

The way Robert (not the object) swings

I’d thought I’d share my take on the necessity of inheritance overall, and what syntax or solution to use when needed and justified.

Is there really a huge need for super calls?

First, I’d say that while it’s all nice and fine with super method calls, in my experience at least, there have been extremely few, if any, real live cases where I have felt a strong need, a mandatory path to go, with super relations. And apparently I’m not alone with this opinion. Douglas Crockford states:

I have been writing JavaScript for 8 years now, and I have never once found need to use an uber function. The super idea is fairly important in the classical pattern, but it appears to be unnecessary in the prototypal and functional patterns. I now see my early attempts to support the classical model in JavaScript as a mistake.

What syntax to use?

However, for those cases you need some sort of inheritance, what syntax should you use? Personally, I’d say that while I’m somewhat attracted to the class-syntax-like implementations, I prefer using the prototype approach for a number of reasons:

  • It’s native, i.e. no dependencies on other code.
  • Freedom of style and version, i.e. if it depended on other code, it would also depend on version of and implementor of that code.
  • Easy readability. I’m sure some of you would want to contradict me, but personally I think the prototype syntax is very easy to look at and understand.
  • Leaving the code to someone else. If you have used a native JavaScript solution, everyone knowing JavaScript will immediately understand it and be able to maintain or extend it. Not the same thing with custom code.

Is there a need for inheritance?

However, I would like to even take it one step further than above. It seems like a number of people overuse inheritance ever so often, ending up in spending most time overriding properties and methods in an object’s parent object, than actually using the parent object as an advantage.

For me, I tend to use the Yahoo JavaScript Module Pattern almost all of the time, and I’m quite happy with it! I ported DOMAssistant to it as well, and it’s a move I don’t regret.

The downside of the pattern is that you can’t (not easily, at least), create several instances of the same object. However, the need for this comes very seldom for me, and when it does, I prefer having used a good namespace I can extend (perhaps based on a custom method in the main object), instead of regular, or “true”, inheritance. A good example of my approach is How to create a plugin for DOMAssistant.

Embrace and join us!

I would humbly like to ask of you to embrace JavaScript. Don’t try to make it into Java, C or any other language. Learn to love it and its dynamic, loose and prototypical nature, and go with the flow. When you stop fighting is when you truly understand how wonderful JavaScript is!

14 comments

  • Steven Clark
    October 6th, 2008 at 1:40

    Interesting, I’ve done a fair bit of Java and understand class inheritance well enough, but JavaScript I’m pretty weak on…

    If you’ve missed it (which I’d be surprised) the Open Web Podcast episode 2 has a bit of a discussion of the inheritance issue, which is kind of interesting.

    http://openwebpodcast.com/

  • Steven Clark
    October 6th, 2008 at 1:41

    Its at about 35 minutes into episode 2. Sorry I should have mentioned that. :)

  • Anders Ytterström
    October 6th, 2008 at 10:33

    Nice read! Yesterday I finished reading about metaprogramming in JavaScript (Art and Science of JavaScript, Sitepoint), so it was a good coincidence that you blogged about it.

    Since I’m bound to Prototype in my current project at work, I stick to their class-like inheritence during office-time. On my own though (no libraries here except DLite), I will start to use the module pattern since it make sense to me.

  • Andrea Giammarchi
    October 6th, 2008 at 10:42

    Hi Robert, good stuff as usual :-)

    The only thing is: why people completely ignore my document? :P

  • Robert Nyman - author
    October 6th, 2008 at 21:24

    Steven,

    Interesting, thanks for the tip!

    Anders,

    Glad you liked it! The metaprogramming chapter is my favorite chapter in a JavaScript ever (or at least for a long long time)!

    Kudos for using dLite!

    By the way, would you say that by using Prototype at work for inheritance, that you might overuse inheritance inadvertedly or not?

    Andrea,

    Thanks! I haven’t fully read your document, but it looks quite good!

  • mdmadph
    October 6th, 2008 at 22:49

    In ExtJS, I’ve actually used super functions here and there, cause there’s so much inheritance going on everywhere, but that’s about it.

  • Robert Nyman - author
    October 7th, 2008 at 20:02

    mdmadph,

    But is that the framework pushing you into using it, or just that it would’ve been needed when you had it, no matter which JavaScript library you were using?

  • Stefan Van Reeth
    October 7th, 2008 at 23:05

    You hava a strong case Robert, and I agree that for websites your approach is certainly the way to go. JavaScript is prototype based and should be used as such.

    However, I feel that in some cases it can be real usefull to mimic class based languages in some respects. Again it’s utterly dependent on user case and personal style, but for larger codebases, I prefer such an approach. However, this has issues as u describe.

    What is needed for the class based emulation approach is something that gives us the goodies from other languages, without sacrificing native js syntax and behaviour. I do know a solution, but it’s in-house developed (I own it, but I agreed not to make it public yet). Forgive me to bring it up here, but I need it to illustrate my views.

    To cut short, it’s possible to merge the two approaches gracefully. At home I can make class-like structures that I can use the native way, without any further calls to Class.extend() or something similiar. All magic is done by putting a few calls into the constructor and after that u can instantiate the classical way (ie with ‘new’).

    Since I constructed this little lib, my productivity has increased dramatically. I now can have private, protected and static methods/properties. I have access control to classes and methods. When debugging I now get meaningfull errors, my objects can be introspected without writing endless for-in loops, etc. The trade-off is an increased memory usage, but that only shows when one creates something silly like 100.000 classes, and even then we’re not talking megabytes here.

    While I agree that such things are overkill for ordinary websites, for larger projects I feel classical js falls short. At some point it pays off to start using a framework, if only to make the codebase easier to maintain. The way I use MF - Mystery Framework ;) - I have the best of both worlds. I have all the benefits of js prototypical nature AND the ease of constraints like we know from Java. Lovely when the codebase surpasses the 1000 lines or so.

    Forgive me this elaborate post again, but it has been a while and I don’t seem to be able to post anything short anyway :D

    Cheers to all that made it this far!!!

  • Robert Nyman - author
    October 8th, 2008 at 8:46

    Stefan,

    Thanks for sharing! I was hoping someone would express their love for a class-based approach. :-)

    It depends on a few factors, as you say: in very, very large projects it might become useful, but my estimate is, like you say, that memory usage will increase (and while not dramatically, every byte counts for me).

    In terms of private and protected properties and methods, the Yahoo Module Pattern offers you just that: one part which can be private and another with protected or public methods.

    Regarding your JavaScript framework, if it ever becomes official, please let me know! :-)

  • JavaScript: how to get private, privileged, public and static members (properties and methods) - Robert’s talk - Web development and Internet trends
    October 14th, 2008 at 13:26

    [...] reading JavaScript inheritance - how and why and Explaining JavaScript scope and closures, I thought we’d combine the knowledge gained to [...]

  • JavaScript inheritance - experimenting with syntax alternatives and private variables - Robert’s talk - Web development and Internet trends
    October 21st, 2008 at 23:33

    [...] reading this article, I strongly recommend reading JavaScript inheritance - how and why and Explaining JavaScript scope and closures first, since many phenomenon below will have their [...]

  • Anders Ytterström
    October 22nd, 2008 at 19:13

    Robert,

    The three of us whom write javascript has a silent agreement to avoid it, I think. There are times when it is tempting to do it just because you can, but one use to find a more straightforward way to solve the problem during the coffee break. :)

  • Robert Nyman - author
    October 22nd, 2008 at 20:43

    Anders,

    :-)

  • JavaScript namespacing - an alternative to JavaScript inheritance - Robert’s talk - Web development and Internet trends
    October 29th, 2008 at 18:10

    [...] talking about JavaScript and inheritance, something that often go amiss from the discussion is the alternative of using proper namespacing [...]

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

Top results