2012-11-11

Daddy, what does the "new" keyword do?


Sit down, and I'll tell you. Ok, it creates a new context object for you, then you'll have a new this to work with. This object will be the return value of the expression starting with new. For example,
> function Dog() { this.name = "poo" }
undefined
> new Dog().name
'poo'
But daddy, what happens if you accidentally forget to use new?
Um, er, lemme see.
> Dog().name
TypeError: Cannot read property 'name' of undefined
So, your constructor gets called, but nothing is returned and your Dog is undefined.
But what happened to the name?
Well, it's the name of the Window or what ever your "global object" is, depending on your execution environment. But its bed time now, good night.
< one hour passes >
Dad! I can't get no sleep! What if I return something from my Dog constructor?
< starts node.js >
Well, if you call it with new, the return value is discarded. If you forget the new, the expression evaluates to the return value.
But dad, that makes no sense and can cause unexpected application errors at runtime!!
That's right, son. That's why daddy avoids the new and this keywords. Now good night.

3 comments:

  1. Cool story. Do you have any idea why does node.js handle the return value of constructors in such a non-standard way? Is this a bug or some weird design decision? V8 in Chrome does the right thing and the new Dog returns the return value of the constructor instead, if it's an object.

    ReplyDelete
  2. You are bit wrong with new() and return object. In case you return non-primitive type from constructor object, it would be returned instead of newly created object.

    Check this out,

    http://stackoverflow.com/questions/6750880/javascript-how-does-new-work-internally

    ReplyDelete
  3. That's even crazier, man :) Glad you shared it, though.

    Quite unbelievable that the type of the returned object affects whether it's actually returned or discarded. Someone must have been smoking more than cigarettes.

    ReplyDelete