Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is JavaScript's "new" keyword considered harmful?

Tags:

javascript

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?

like image 554
Pablo Fernandez Avatar asked Dec 20 '08 15:12

Pablo Fernandez


People also ask

What happens when you use new keyword?

The new keyword has to be placed before the constructor function call and will do the following things: Creates a new object. Sets the prototype of this object to the constructor function's prototype property. Binds the this keyword to the newly created object and executes the constructor function.

What does New keyword mean?

New keyword in JavaScript is used to create an instance of an object that has a constructor function. On calling the constructor function with 'new' operator, the following actions are taken: A new empty object is created.

What happens when we use new keyword in JavaScript?

When a function is called with the new keyword, the function will be used as a constructor. new will do the following things: Creates a blank, plain JavaScript object. For convenience, let's call it newInstance .

Is the new keyword used?

The Java new keyword is used to create an instance of the class. In other words, it instantiates a class by allocating memory for a new object and returning a reference to that memory. We can also use the new keyword to create the array object.


2 Answers

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 new keyword has several advantages over building each object from scratch:

  1. Prototype inheritance. While often looked at with a mix of suspicion and derision by those accustomed to class-based OO languages, JavaScript's native inheritance technique is a simple and surprisingly effective means of code re-use. And the new keyword is the canonical (and only available cross-platform) means of using it.
  2. Performance. This is a side-effect of #1: if I want to add 10 methods to every object I create, I could just write a creation function that manually assigns each method to each new object... Or, I could assign them to the creation function's prototype and use new to 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, new has 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:

function foo() {    // if user accidentally omits the new keyword, this will     // silently correct the problem...    if ( !(this instanceof foo) )       return new foo();        // constructor logic follows... } 

Now you can have the advantages of new without having to worry about problems caused by accidentally misuse. 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:

if ( !(this instanceof arguments.callee) )     throw new Error("Constructor called as a function"); 

(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.)

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 with is especially enlightening for those of us who initially dismissed this much-maligned feature as a gimmick).

like image 123
Shog9 Avatar answered Oct 07 '22 11:10

Shog9


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.

like image 26
some Avatar answered Oct 07 '22 12:10

some