JS: Creating instances without new

During a code review recently I was looking at some code that was using the new keyword to create an instance e.g:

var inst = new MyConstructor();

The context object when new isn't used

The code contained a safeguard to bail if the new keyword wasn't used. Which is a good idea because if the the new keyword is omitted, the context will be window.

This outputs:

"[object Window]"
"[object Object]"

Making a flexible constructor

To move away from the need to require new we ended up changing the constructor to allow instance creation both with and without new. This meant that we could create our objects more directly. In our case the code was passing the objects as args so getting rid of new simplified things quite a bit.

This outputs:

"foo1"
"foo2"

So now:

var inst = MyConstructor();

and

var inst = new MyConstructor();

Are equivalent. At least if you forget the new keyword you're not going to get burned by having the context object be window.

Using arguments to DRY up the signature

One issue that my colleague Kumar raised with this approach is it means you need to update the signature in two places when it changes. Not a huge deal but it would be nice to get away from that.

Immediately I thought of arguments. But you can't use apply and new together to create an instance.

So here's an alternative that deals with that:

Here we create an object with the MyConstructor prototype and then call the constructor using that object as the context. As arguments is used you avoid having 2 places to update the signature.

Here's the output:

["foo1", "bar1"]
["foo2", "bar2"]
["whatever", "bar1"]
["foo2", "bar2"]
true
true

Here's that example on JSBin so you can see it in action.

Over to you

Found a better, more elegant way to do this? Leave a comment with a code example.

Show Comments