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 am newbie to Javascript so maybe I am just not too experienced in providing a good view point to this. Yet I want to share my view on this "new" thing.
I have come from the C# world where using the keyword "new" is so natural that it is the factory design pattern that looks weird to me.
When I first code in Javascript, I don't realize that there is the "new" keyword and code like the one in YUI pattern and it doesn't take me long to run into disaster. I lose track of what a particular line is supposed to be doing when looking back the code I've written. More chaotic is that my mind can't really transit between object instances boundaries when I am "dry-running" the code.
Then, I found the "new" keyword which to me, it "separate" things. With the new keyword, it creates things. Without the new keyword, I know I won't confuse it with creating things unless the function I am invoking gives me strong clues of that.
For instance, with var bar=foo();
I have no clues as what bar could possibly be.... Is it a return value or is it a newly created object? But with var bar = new foo();
I know for sure bar is an object.
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 test this
in every constructor.
http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html
Here's the gist of the technique:
/**
* Wraps the passed in constructor so it works with
* or without the new keyword
* @param {Function} realCtor The constructor function.
* Note that this is going to be wrapped
* and should not be used directly
*/
function ctor(realCtor){
// This is going to be the actual constructor
return function wrapperCtor(){
var obj; // object that will be created
if (this instanceof wrapperCtor) {
// Called with new
obj = this;
} else {
// Called without new. Create an empty object of the
// correct type without running that constructor
surrogateCtor.prototype = wrapperCtor.prototype;
obj = new surrogateCtor();
}
// Call the real constructor function
realCtor.apply(obj, arguments);
return obj;
}
function surrogateCtor() {}
}
Here's how to use it:
// Create our point constructor
Point = ctor(function(x,y){
this.x = x;
this.y = y;
});
// This is good
var pt = new Point(20,30);
// This is OK also
var pt2 = Point(20,30);
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;
or var bar = baz();
where baz isn't an object creating method seems far more dangerous.
new
isn't required and should be avoidedvar str = new String('asd'); // type: object
var str = String('asd'); // type: string
var num = new Number(12); // type: object
var num = Number(12); // type: number
new
is required, otherwise you'll get an errornew Date().getFullYear(); // correct, returns the current year, i.e. 2010
Date().getFullYear(); // invalid, returns an error
I have just read some parts of his Crockfords book "Javascript: The Good Parts". I get the feeling that he considers everything that ever has bitten him as harmful:
About switch fall through:
I never allow switch cases to fall through to the next case. I once found a bug in my code caused by an unintended fall through immediately after having made a vigorous speech about why fall through was sometimes useful. (page 97, ISBN 978-0-596-51774-8)
About ++ and --
The ++ (increment) and -- (decrement) operators have been known to contribute to bad code by encouraging exessive trickiness. They are second only to faulty architecture in enabling viruses and other security menaces. (page 122)
About new:
If you forget to include the new prefix when calling a constructor function, then this will not be bound to the new object. Sadly, this will be bound to the global object, so instead of augmenting your new object, you will be clobbering global variables. That is really bad. There is no compile warning, and there is no runtime warning. (page 49)
There are more, but I hope you get the picture.
My answer to your question: No, it's not harmful. but if you forget to use it when you should you could have some problems. If you are developing in a good environment you notice that.
Update
About a year after this answer was written the 5th edition of ECMAScript was released, with support for strict mode. In strict mode, this
is no longer bound to the global object but to undefined
.
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"
var foo = function () {
var pub= { };
return pub;
}
var bar = foo();
Alternatively you could so this:
function foo() { }
var bar = new foo();
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.