tags:

views:

310

answers:

2

The problem is that I need to create a new instance of the passed class

Is there a way to rewrite this function, so it could accept any number of arguments?

function createInstance(ofClass, arg1, arg2, arg3, ..., argN){
  return new ofClass(arg1, arg2, arg3, ..., argN);
}

This function should create an instance of the passed class. Example:

var SomeClass = function(arg1, arg2, arg3){
   this.someAttr = arg3;
   .....
}
SomeClass.prototype.method = function(){}

var instance = createInstance(SomeClass, 'arg1', 'arg2', 'arg3');

So this should be true.

instance instanceof SomeClass == true

Right now, I've just limited N to 25, with hope that more arguments are rarely used.

+4  A: 

There is always an arguments array

Tim Büthe
I know about it, please give an example how would you use it to rewrite this function.
valums
Could you give a concrete example? Do you have to pass all args in the constructor? Doesn't Djko's Answer work? http://stackoverflow.com/questions/1271657/javascript-factory-with-optional-arguments/1271673#1271673
Tim Büthe
+5  A: 

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.

Blixt
Sorry, my question wasn't clear enough, the problem is that I need a new instance of obj, so your answer doesn't solve my problem, but upvoted for mention that arguments in not an Array.
valums
I understand your question better now. Read my update for how to solve your problem.
Blixt
I'd appreciate an explanation for -1, especially considering that this is the only answer that, to the best of my knowledge, works (when taking John Resig's change into consideration.) I see someone finally brought up `eval` as a solution, but I wouldn't touch that with a stick, I'm afraid.
Blixt