The other answers are on the right track, but none of them mention that you have to be aware of the fact that arguments
is not an Array
. It's a special structure that behaves like an Array
.
So before you use it like an Array
, you can convert it to one like this:
function createInstance(cls) {
// This will use the slice function of the Array type, effectively converting
// the arguments structure to an Array and throwing away the first argument,
// which is cls.
var args = Array.prototype.slice.call(arguments, 1);
return cls.apply(this, args);
}
Sorry, I just copied the code with constructor
etc. and didn't think about what it would actually do. I've updated it now to what you want. You'll find that it's calling the constructor without new
, so you won't get the same behavior. However, John Resig (author of jQuery) wrote on this very issue.
So based on John Resig's article you've got two ways to solve it. The more elaborate solution will be the most transparent to the user, but it's up to you which solution you choose.
Here is a "perfect" solution if you only intend to support browsers that have the Object.create
function (which is a pretty big percentage now compared to three years ago):
function createInstance(cls) {
var obj = Object.create(cls.prototype);
var args = Array.prototype.slice.call(arguments, 1);
cls.apply(obj, args);
return obj;
}
The resulting objects from both new cls(x)
and createInstance(cls, x)
should be identical.