Because of the difficulty in calling a constructor with an arbitrary list of arguments in ES5, I've seen some code that does something like this. It's not elegant at all, but it does get the job done as long as there's a limit to how many arguments you need to support:
function createBar() {
if (arguments.length === 0) {
return new Bar();
} else if (arguments.length === 1) {
return new Bar(arguments[0]);
} else if (arguments.length === 2) {
return new Bar(arguments[0], arguments[1]);
} else if (arguments.length === 3) {
return new Bar(arguments[0], arguments[1], arguments[2]);
} else if (arguments.length === 4) {
return new Bar(arguments[0], arguments[1], arguments[2], arguments[3]);
} else {
throw new Error("too many arguments for Bar()");
}
}
You could even make a generic version of this that you pass in the constructor for so you can reuse the if/else
code for any constructor:
// generic way of calling constructor with variable args
function createFn(fn /* other args here */) {
if (arguments.length === 1) {
return new fn();
} else if (arguments.length === 2) {
return new fn(arguments[1]);
} else if (arguments.length === 3) {
return new fn(arguments[1], arguments[2]);
} else if (arguments.length === 4) {
return new fn(arguments[1], arguments[2], arguments[3]);
} else if (arguments.length === 5) {
return new fn(arguments[1], arguments[2], arguments[3], arguments[4]);
} else {
throw new Error("too many arguments for Bar()");
}
}
function createBar() {
var args = Array.prototype.slice.call(arguments);
args.unshift(Bar);
return createFn.apply(null, args);
}
In cases like this where you control all the code, it's often just better to redesign the constructor to accept a single object with optional properties and then it's trivial to solve this problem in ES5 as you just pass the single object through and the constructor looks for what properties are on the object.
Here's another scheme that I just came across: Use of .apply() with 'new' operator. Is this possible?
which is similar to what you saw with .bind()
in TypeScript.