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, Scriptaculous 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?
I wrote a post on how to mitigate the problem of calling a constructor without the new keyword.
It's mostly didactic, but it shows how you can create constructors that work with or without
new
and doesn't require you to add boilerplate code to testthis
in every constructor.http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html
Here's the gist of the technique:
Here's how to use it:
Another case for new is what I call Pooh Coding. Winnie the Pooh follows his tummy. I say go with the language you are using, not against it.
Chances are that the maintainers of the language will optimize the language for the idioms they try to encourage. If they put a new keyword into the language they probably think it makes sense to be clear when creating a new instance.
Code written following the language's intentions will increase in efficiency with each release. And code avoiding the key constructs of the language will suffer with time.
EDIT: And this goes well beyond performance. I can't count the times I've heard (or said) "why the hell did they do that?" when finding strange looking code. It often turns out that at the time when the code was written there was some "good" reason for it. Following the Tao of the language is your best insurance for not having your code ridiculed some years from now.
Javascript being dynamic language there a zillion ways to mess up where another language would stop you.
Avoiding a fundamental language feature such as
new
on the basis that you might mess up is a bit like removing your shiny new shoes before walking through a minefield just in case you might get your shoes muddy.I use a convention where function names begin with a lower case letter and 'functions' that are actually class definitions begin with a upper case letter. The result is a really quite compelling visual clue that the 'syntax' is wrong:-
On top of this good naming habits help. After all functions do things and therefore there should be a verb in its name whereas classes represent objects and are nouns and adjectives with no verb.
Its interesting how SO's syntax colouring has interpretted the code above.
I agree with pez and some here.
It seems obvious to me that "new" is self descriptive object creation, where the YUI pattern Greg Dean describes is completely obscured.
The possibility someone could write
var bar = foo;
orvar bar = baz();
where baz isn't an object creating method seems far more dangerous.The rationale behind not using the new keyword, is simple:
By not using it at all, you avoid the pitfall that comes with accidentally omitting it. The construction pattern that YUI uses, is an example of how you can avoid the new keyword altogether"
Alternatively you could so this:
But by doing so you run risk of someone forgetting to use the new keyword, and the this operator being all fubar. AFAIK there is no advantage to doing this (other than you are used to it).
At The End Of The Day: It's about being defensive. Can you use the new statement? Yes. Does it make your code more dangerous? Yes.
If you have ever written C++, it's akin to setting pointers to NULL after you delete them.
I think new is evil, not because if you forget to use it by mistake it might cause problems but because it screws up the inheritance chain, making the language tougher to understand.
JavaScript is prototype-based object-oriented. Hence every object MUST be created from another object like so
var newObj=Object.create(oldObj)
. Here oldObj is called the prototype of newObj (hence "prototype-based"). This implies that if a property is not found in newObj then it will be searched in oldObj. newObj by default will thus be an empty object but due to its prototype chain it appears to have all the values of oldObj.On the other hand if you do
var newObj=new oldObj()
, the prototype of newObj is oldObj.prototype, which is unnecessarily difficult to understand.The trick is to use
It is inside this function and only here that new should be used. After this simply use the Object.create() method. The method resolves the prototype problem.