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"); }); ```

Original source

Related problems