How can I call a javascript constructor using call or apply?
apply, call, javascript
Solution
Try this:
function conthunktor(Constructor) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var Temp = function(){}, // temporary constructor
inst, ret; // other vars
// Give the Temp constructor the Constructor's prototype
Temp.prototype = Constructor.prototype;
// Create a new instance
inst = new Temp;
// Call the original Constructor with the temp
// instance as its context (i.e. its 'this' value)
ret = Constructor.apply(inst, args);
// If an object has been returned then return it otherwise
// return the original instance.
// (consistent with behaviour of the new operator)
return Object(ret) === ret ? ret : inst;
}
}
Problem
How could I generalise the function below to take N arguments? (Using call or apply?) Is there a programmatic way to apply arguments to 'new'? I don't want the constructor to be treated like a plain function. ``` /** * This higher level function takes a constructor and arguments * and returns a function, which when called will return the * lazily constructed value. * * All the arguments, except the first are pased to the constructor. * * @param {Function} constructor */ function conthunktor(Constructor) { var args = Array.prototype.slice.call(arguments, 1); return function() { console.log(args); if (args.length === 0) { return new Constructor(); } if (args.length === 1) { return new Constructor(args[0]); } if (args.length === 2) { return new Constructor(args[0], args[1]); } if (args.length === 3) { return new Constructor(args[0], args[1], args[2]); } throw("too many arguments"); } } ``` qUnit test: ``` test("conthunktorTest", function() { function MyConstructor(arg0, arg1) { this.arg0 = arg0; this.arg1 = arg1; } MyConstructor.prototype.toString = function() { return this.arg0 + " " + this.arg1; } var thunk = conthunktor(MyConstructor, "hello", "world"); var my_object = thunk(); deepEqual(my_object.toString(), "hello world"); }); ```