Summary
JavaScript is an object-oriented language, but it does not have the concept of classes. Instead, JavaScript relies on an object's prototype to encapsulate information. In a recent blog post, JQuery author John Resig describes how JavaScript inheritance can be made easier.
Advertisement
Developers coming from Java to JavaScript are often surprised at JavaScript's lack of class support. An object-oriented—as well as functional—language, JavaScript supports object-oriented constructs via a prototype system.
Because prototypes are a somewhat foreign notion to those used to working with classes, many JavaScript libraries and frameworks aim to provide some notion of classes, including inheritance based on classes. In a recent blog post, Simple JavaScript Inheritance, John Resig, author of the JQuery library, explains how to provide a simple class-like facility to specify inheritance for JavaScript.
Using Resig's techniques allows developers to write code in a more familiar style, such as:
var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
});
var Ninja = Person.extend({
init: function(){
this._super( false );
},
dance: function(){
// Call the inherited version of dance()
return this._super();
},
swingSword: function(){
return true;
}
});
Resig highlights the most important benefits of his technique:
Creating a constructor had to be simple (in this case simply providing an init method does the trick).
In order to create a new 'class' you must extend (sub-class) an existing class.
All of the 'classes' inherit from a single ancestor: Class. Therefore if you want to create a brand new class it must be a sub-class of Class.
And the most challenging one: Access to overridden methods had to be provided (with their context properly set). You can see this with the use of this._super(), above, calling the original init() and dance() methods of the Person super-class.
The rest of Resig's blog post describes the technique in detail, and shows why it yields an easier programming model than a more straightforward use of prototypes.
What do you think of Resig's technique? Which JavaScript library do you find the easiest to use for OO development?
I think maybe Javascript language designers should fix its prototype system to be easy to use. I just don't think bolting an arguably inferior system (Class system) on top of prototypes is the solution. Make prototypes friendly and easy. Javascript should play up its strengths. If its prototype nature is not a strength, then instead of bolting a class system on top of it, it should be abandoned.
Meanwhile I would say, avoid classes and use functional style with Javascript. And don't write huge programs in the current flavors of Javascript. It's not ready for it yet. Maybe wait for ES4 if you have an urge to write a huge Javascript application.
Prototyping is a very elegant concept and fits a lot better with dynamic languages than class-based-inheritance. User-defined type hierarchies are mostly useless in languages that don't do any compile type type checking. The main (nearly only) good reason to subclass in a language like Java is for the sake of polymorphism. In dynamic languages, all calls are polymorphic. If the receiver has a method, then you can call it. The type of the receiver is irrelevant. Prototyping, essentially, provides inheritance (or delegation, if you prefer) without the baggage of type hierarchies.
That said, Javascript's implementation of prototyping is clunky. Foo.prototype = bar; does not mean "the prototype of Foo is bar". It means "The objects created when Foo is used as a constructor will have bar as their prototype." Also, Javascript hides the reference to the prototype object without providing a "super" mechanism (unless you count "__proto__"), which makes things unnecessarily difficult.