In another question, a user pointed out that the new keyword was dangerous to use and proposed a solution to object creation that did not use new. I didn’t believe that was true, mostly because I’ve used Prototype, Script.aculo.us and other excellent JavaScript libraries, and everyone of them used the new keyword.
In spite of that, yesterday I was watching Douglas Crockford’s talk at YUI theater and he said the exactly same thing, that he didn’t use the new keyword anymore in his code (Crockford on JavaScript – Act III: Function the Ultimate – 50:23 minutes).
Is it ‘bad’ to use the new keyword? What are the advantages and disadvantages of using it?
Crockford has done a lot to popularize good JavaScript techniques. His opinionated stance on key elements of the language have sparked many useful discussions. That said, there are far too many people that take each proclamation of "bad" or "harmful" as gospel, refusing to look beyond one man’s opinion. It can be a bit frustrating at times.
Use of the functionality provided by the
newkeyword has several advantages over building each object from scratch:newkeyword is the canonical (and only available cross-platform) means of using it.prototypeand usenewto stamp out new objects. Not only is this faster (no code needed for each and every method on the prototype), it avoids ballooning each object with separate properties for each method. On slower machines (or especially, slower JS interpreters) when many objects are being created this can mean a significant savings in time and memory.And yes,
newhas one crucial disadvantage, ably described by other answers: if you forget to use it, your code will break without warning. Fortunately, that disadvantage is easily mitigated – simply add a bit of code to the function itself:Now you can have the advantages of
newwithout having to worry about problems caused by accidentally misuse.John Resig goes into detail on this technique in his Simple "Class" Instantiation post, as well as including a means of building this behavior into your "classes" by default. Definitely worth a read… as is his upcoming book, Secrets of the JavaScript Ninja, which finds hidden gold in this and many other "harmful" features of the JavaScript language (the chapter on
withis especially enlightening for those of us who initially dismissed this much-maligned feature as a gimmick).A general-purpose sanity check
You could even add an assertion to the check if the thought of broken code silently working bothers you. Or, as some commented, use the check to introduce a runtime exception:
Note that this snippet is able to avoid hard-coding the constructor function name, as unlike the previous example it has no need to actually instantiate the object – therefore, it can be copied into each target function without modification.
ES5 taketh away
As Sean McMillan, stephenbez and jrh noted, the use of
arguments.calleeis invalid in ES5’s strict mode. So the above pattern will throw an error if you use it in that context.ES6 and an entirely harmless
newES6 introduces Classes to JavaScript – no, not in the weird Java-aping way that old-school Crockford did, but in spirit much more like the light-weight way he (and others) later adopted, taking the best parts of prototypal inheritance and baking common patterns into the language itself.
…and part of that includes a safe
new:But what if you don’t want to use the new sugar? What if you just want to update your perfectly fine old-style prototypal code with the sort of safety checks shown above such that they keep working in strict mode?
Well, as Nick Parsons notes, ES6 provides a handy check for that as well, in the form of
new.target:So whichever approach you choose, you can – with a bit of thought and good hygiene – use
newwithout harm.