JavaScript Inheritance

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:

* Simple JavaScript Inheritance – John Resig
* A Base Class for JavaScript Inheritance – Dean Edwards
* Defining classes and inheritance – Prototype JavaScript Framework

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!

http://robertnyman.com/2008/10/06/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>