apply the new operator

A while back I was trying to write a function would return a new instance of a function which had n number of arguments. Just last week I finally figured out how. Below is a completely generic example of how to return a new instance of a function regardless if the developer uses the new operator.

1
2
3
4
5
6
function MyFunc() {
    if (!( this instanceof arguments.callee ))
        return arguments.callee.apply( new arguments.callee(), arguments );
    // do stuff here
    return this;
}

The key to have this syntax work is the return this; at the bottom of the function. Fortunately we can shrink down the verbosity of the expression by using the function name. Below is a simple example to create an object that will sum its arguments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function SumObj() {
    if (!( this instanceof SumObj ))
        return SumObj.apply( new SumObj(), arguments );
    this.args = Array.prototype.slice.call( arguments );
    return this;
}

SumObj.prototype.sum = function() {
    var total = 0,
        i = 0;
    for ( ; i < this.args.length; i++ )
        total += this.args[i];
    return total;
}

SumObj( 1, 2, 3 ) === { args : [ 1, 2, 3 ]};
SumObj( 2, 3, 5 ).sum() === 10;