The usual approach to this is to separate instantiation from initialization. That way, you can defer initialization to the point where your subclass has actual arguments to work with. Of course, the downside of doing that is that barring your putting controls around it, you can have instances with invalid states. One of the purposes of passing arguments to constructors, after all, is that sufficiently invalid arguments can be dealt with by throwing exceptions, preventing the caller from having a reference to an invalid instance.
Here, that would look something like this (but don't be put off, keep reading, there are ways to improve it):
// base class
var Item = function() {
this.initialize.apply(this, arguments);
};
Item.prototype.initialize = function( type, name ) {
this.type = type;
this.name = name;
};
// actual class (one of many related alternatives)
var Book = function() {
this.initialize.apply(this, arguments);
};
Book.prototype = new Item();
Book.prototype.initialize = function( title, author ) {
Item.prototype.initialize.call(this, 'book', title);
this.author = author;
};
// instances
var book = new Book('Hello World', 'A. Noob');
(Edit: The above was off-the-cuff; check out AnthonyWJones's answer for a much more terse version with a clever twist on initialization, although it doesn't demonstrate supercalls, which will still be as awkward as the above.)
As you can see, you end up doing a fair bit of typing to get all this done, and supercalls (calls to the superclass) are to be blunt fairly ugly. (Also, just using the arguments
array in a function slows it down markedly in some implementations.) That's why you end up with helpers in libraries like Prototype, Resig's implementation, etc.
A number of those helper approaches, though, introduce a lot of inefficiency, use of never-standardized language features (Function#toString
, for instance), and/or cause incompatibility with the new "strict" mode of JavaScript. I've written up a blog post showing how to do this rather more tersely whilst keeping supercalls efficient and strict-compliant.
Regarding doing away with new
: I wouldn't, but I wouldn't call doing so being a newbie working against the language -- Crockford advocates not using it, for instance, and he's no newbie. To my mind, though, there's no reason to avoid it. The reasons people sometimes give are just around newbies making mistakes related to it, which you don't immediately seem likely to and which in any case just indicate that the newbies need to be mentored a bit.