I’ve claimed in a couple talks recently that the ES6 expression
new Foo(...args)
is impossible to implement in ES3 and only became possible in ES5 with Function.prototype.bind:
Function.prototype.applyNew = function applyNew(a) {
return new (this.bind.apply(this, [,].concat(a)))();
};
Foo.applyNew(args)
This works by closing the function over arguments array a with an undefined receiver (the [,] expression creates an array of length 1 but a hole at element 0). Since a function created by Function.prototype.bind ignores the bound receiver when called with new, this has the same behavior as the ES6 expression.
But I should not have counted ES3 out so easily — with the magic of eval, many impossible things are possible.
Function.prototype.applyNew = function applyNew(a) {
return eval("new this(" +
a.map(function(x, i) {
return "a[" + i + "]";
}).join(",") +
")");
};
Foo.applyNew(args)
Thanks to Trevor Norris for awakening me from my dogmatic slumber. His approach won’t work for functions like String that have different call and construct behavior, but he reminded me that I’d seen this solved before with eval.
Edit: Oops, the applyNew method doesn’t take a function argument, it uses this as the function. That’s what I get for posting without testing!
