JavaScript inheritance – how and why

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!

Posted in Developing,DOMAssistant,JavaScript,Technology |

31 Comments

  • Steven Clark says:

    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 says:

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

  • 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.

  • Hi Robert, good stuff as usual :-)

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

  • Robert Nyman says:

    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 says:

    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 says:

    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 says:

    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 says:

    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! :-)

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

  • [...] 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 [...]

  • 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. :)

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

  • rajakvk says:

    <blockquote cite="">I would humbly like to ask of you to embrace JavaScript. </cite>

    Well said…

  • Juan Mendes says:

    I have a number of comments. Embracing Javascript is one thing. Saying that there's no use for inheritance on the client-side of web apps is just too far fetched. It is true that people misuse inheritance, but that doesn't mean there's on use for it. Douglas may not have found uses for it, maybe because he hasn't built a system where components are built on top of other components. In the DOM, everything extends Element. In Ext-js everything is a component and that allows for code to treat any subclasses simply as a component.

    Enough of that, let's talk about your approach to using inheritance. This approach suffers from a problem. What if your base class requires parameters to be initialized? Even worse, what if there are side effects to the base class being instantiated? You can't just call the constructor to establish inheritance. You could if you hacked all your constructors to know that they were being called for inheritance. That would just be plain ugly

    However, there is a solution to this which involves surrogate constructors. This was developed by a co-worker here at our company within a library he wrote called class.js. Basically this is what you would do.

    <code>

    // Function to be used as a surrogate constructor to avoid

    // instantiating a parent class just to setup inheritance

    function surrogateCtor() {}

    function Being (name) {

    this.name = name;

    console.log('Being constructor called');

    }

    Being.prototype.breathes = function () {

    return true;

    };

    // An object which inherits Being:

    function Human(name, blogs) {

    this.blogs = blogs;

    // Call the super constructor

    Being.call(this, name);

    }

    // Establish inheritance without calling the parent's constructor

    surrogateCtor.prototype = Being.prototype;

    Human.prototype = new surrogateCtor();

    // Set the constructor back on the prototype since we used some trickery

    Human.prototype.constructor = Human;

    Human.prototype.getsBored = function () {

    return !this.blogs;

    };

    // —— Testing code——————

    var rob = new Human("Robert", true);

    console.log("Name is " + rob.name);

    console.log("Breathes:" + rob.breathes())

    console.log("Gets bored:" + rob.getsBored())

    // Outputs:

    // Being constructor called (just once, awesome)

    // Name is Robert

    // Breathes:true

    // Gets bored: false

    </code>

    This could be abstracted with the following code

    <code>

    Function.prototype.extend = (function() {

    function surrogateCtor (){};

    return function(parentCtor) {

    surrogateCtor.prototype = parentCtor.prototype;

    this.prototype = new surrogateCtor();

    this.prototype.constructor = this;

    };

    })();

    // Abstract base class

    function Shape() {}

    // Extending classes must override these two methods

    Shape.prototype.getSideCount = function (){};

    Shape.prototype.getSideLength = function (){};

    // Common functionality in base

    Shape.prototype.getPerimeter = function () {

    return this.getSideCount() * this.getSideLength();

    }

    // Extends Shape

    function Triangle(sideLength) {

    this.sideLength = sideLength;

    }

    // Extend must be called before adding props to the prototype

    Triangle.extend(Shape);

    Triangle.prototype.getSideCount = function() {

    return 3;

    }

    Triangle.prototype.getSideLength = function() {

    return this.sideLength;

    }

    // — Testing code —–

    var tri = new Triangle(5);

    console.log(tri.getPerimeter());// outputs 15

    </code>

  • Robert Nyman says:

    Juan Mendes,

    I'd like to correct/clarify my statement in the article: I definitely believe there is need and use for inheritance, what I was going for is that probably isn't need to be in the fashion it is with class-based models (i.e. "super"-calling etc).

    Thanks for the code, it was interesting!

    At the end of the day, though, I think we all need to consider what we need and what till be our best way to do it: there's no golden solution for any situation.

  • Juan Mendes says:

    Here's a link to an interesting article at extjs that mentions some pitfalls of getting too "inheritance happy". See the part under "Create a subclass (Option 2)"

    http://www.extjs.com/blog/2009/11/11/advanced-plu

    Not sure how much you care about extjs, but the one of his points is that added functionality through subclassing prohibits the reuse of that functionality in other classes:

  • Michael .H says:

    I observed one thing about Base2 and Prototype. When you call a chain method and you reach the base method, inside the method you have access to the derived object members using “this”. In my opinion once the call is navigating thru the chain on each base class the user should not be able to access the derived class members based on OOP definitions. I also tried a different approach of JavaScript inheritance, it can make use of closures or prototype, it’s up to the way you want to implement it http://dotnetcaffe.blogspot.com/2009/12/javascript-inheritance.html. Regarding what Juan Mendes mentioned about surrogate constructors. Even if it’s more light weight as memory consumption I don’t find elegant. In my case if the base class constructor requires parameters they will be passed from the derived class. Here is an example:

    var Human = MG.Class.Create({
    Gender: null,
    constructor: function(gender) {
    this.Gender = gender;
    },

    GenderString: function() {
    return this.Gender == ‘F’ ? “female” : “male”;
    },

    ToOverride: function() { return “Called from Human”; }
    }, null, null);

    var Individual = MG.Class.Create({
    Unique: null,
    constructor: function(unique) {
    this.Unique = unique;
    },

    IsUnique: function() {
    return this.Unique ? “Yes” : “No”;
    },

    ToOverride: function() { return “Called from Individual which is ” + (this.Unique ? “unique” : “not unique”) + ” / ” + this.base(); }
    }, Human, null);

    var objHuman = new Human(“F”);
    var objIndividual = new Individual(true, “M”);

    In my opinion also a check for parameters of the base constructor should be added. If the derived object does not provide on instantiation the correct number or parameters for the base, then an exception should be triggered.

  • Robert Nyman says:

    Juan,

    Thanks for the link!

    Michael,

    Thanks for sharing! There are some interesting things in there, although my preferred approach is the native prototype syntax for readability, code handover and for being there native in the language without dependencies.

  • [...] Nyman. I came here for this (read it!) and stayed for the rest. Look for “JavaScript series” in the sidebar [...]

  • Ionut Popa says:

    What about using the Revealing module pattern?

    what are the disadvantages of using this instead of the .protoype way?

  • Robert Nyman says:

    Ionut,

    I almost exclusively use the module pattern, and it's mentioned in the post as well. When it comes to inheritance, there could be some tricks you need to and many instances might create performance problems.

    So, adapt your approach to your specific usage situation.

  • Ionut Popa says:

    So when you need multiple instances you use a modified version of this pattern?

  • Robert Nyman says:

    Ionut,

    Please see Douglas Crockford’s presentation for more information (page 66 especially).

  • Matbaa says:

    Was descriptive writing, thank you

  • Joe says:

    If you have done Object Oriented Programming in JavaScript, you will know that you can create a class as follows:

    Person = function(id, name, age){
    this.id = id;
    this.name = name;
    this.age = age;
    alert(‘A new person has been accepted’);
    }

    So far our class person only has two properties and we are going to give it some methods. A clean way of doing this is
    to use its ‘prototype’ object.
    Starting from JavaScript 1.1, the prototype object was introduced in JavaScript. This is a built in object that
    simplifies the process of adding custom properties and methods to all instances of an object.
    Let’s add 2 methods to our class using its ‘prototype’ object as follows:

    Person.prototype = {
    /** wake person up */
    wake_up: function() {
    alert(‘I am awake’);
    },

    /** retrieve person’s age */
    get_age: function() {
    return this.age;
    }
    }

    Now we have defined our class Person. What if we wanted to define another class called Manager which inherits some properties from Person. There is no point redefining all this properties again when we define our Manager class, we can just set it to inherit from the class Person.
    JavaScript doesn’t have built in inheritance but we can use a technique to implement inheritance as follows:

    `Inheritance_Manager = {};`//We create an inheritance manager class (the name is arbitrary)

    Now let’s give our inheritance class a method called extend which takes the baseClass and subClassas arguments.
    Within the extend method, we will create an inner class called inheritance function inheritance() { }. The reason why we are using this inner
    class is to avoid confusion between the baseClass and subClass prototypes.
    Next we make the prototype of our inheritance class point to the baseClass prototype as with the following code:
    inheritance.prototype = baseClass. prototype;
    Then we copy the inheritance prototype into the subClass prototype as follows: subClass.prototype = new inheritance();
    The next thing is to specify the constructor for our subClass as follows: subClass.prototype.constructor = subClass;
    Once finished with our subClass prototyping, we can specify the next two lines of code to set some base class pointers.

    subClass.baseConstructor = baseClass;
    subClass.superClass = baseClass.prototype;

    Here is the full code for our extend function:

    Inheritance_Manager.extend = function(subClass, baseClass) {
    function inheritance() { }
    inheritance.prototype = baseClass.prototype;
    subClass.prototype = new inheritance();
    subClass.prototype.constructor = subClass;
    subClass.baseConstructor = baseClass;
    subClass.superClass = baseClass.prototype;
    }

    Now that we have implemented our inheritance, we can start using it to extend our classes. In this case we are going to
    extend our Person class into a Manager class as follows:

    We define the Manager class

    Manager = function(id, name, age, salary) {
    Person.baseConstructor.call(this, id, name, age);
    this.salary = salary;
    alert(‘A manager has been registered.’);
    }

    we make it inherit form Person

    Inheritance_Manager.extend(Manager, Person);

    If you noticed, we have just called the extend method of our Inheritance_Manager class and passed the subClass Manager in our case and then the baseClass Person. Note that the order is very important here. If you swap them, the inheritance
    will not work as you intended if at all.
    Also note that you will need to specify this inheritance before you can actually define our subClass.
    Now let us define our subClass:

    We can add more methods as the one below. Our Manager class will always have the methods and properties defined in the Person class because it inherits from it.

    Manager.prototype.lead = function(){
    alert(‘I am a good leader’);
    }

    Now to test it let us create two objects, one from the class Person and one from the inherited class Manager:

    var p = new Person(1, ‘Joe Tester’, 26);
    var pm = new Manager(1, ‘Joe Tester’, 26, ‘20.000’);

    Feel free to get full code and more comments at:
    http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx

  • [...] JavaScript Inheritance – How And Why . Robert Nyman . October 6, 2008 [...]

  • [...] JavaScript inheritance – how and why [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>