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.