Which is Better?

Just thought I'd throw this question out to the crowd.

var obj = new function(){ ... };
// OR
var obj = function(){...}();

I prefer the former to the latter because I can assign properties to the object without explicitly having to return an object but I noticed Dustin Diaz did the latter in his latest screencast.

Hands up if this kind of JavaScript minutia just put you to sleep.

Published August 29, 2006 · Updated September 14, 2006
Categorized as JavaScript
Short URL: https://snook.ca/s/656

Conversation

18 Comments · RSS feed
Randy said on August 29, 2006

I tend to use var obj = function(){...}();

Although I don't know why... I think it's just how I learned it and haven't thought to use 'new'. I'm interested to learn if anyone offers any compelling reasons to use one over the other. Teach us, you wise JS gurus.

Andy Kant said on August 29, 2006

I prefer using the "new" keyword because it is more easily understood by people coming from backgrounds in other languages. Even with a JavaScript background, its still confusing syntax.

Johnny K said on August 29, 2006

I prefer using 'new' because I find it more readable.

Thomas Messier said on August 29, 2006

I don't use the "new". Apparently, function expressions are faster because they don't have to be parsed every time they are evaluated as is the case when you use the constructor form (new Function()). There's a pretty exhaustive explanation of the different ways here.

(remove the spaces, I just added them so the long URL wouldn't break the page) [Ed. long url fixed]

Olly said on August 29, 2006

Swooosh!

I have much to learn in the field of javascript :)

Blair said on August 29, 2006

Zzzzzz.... snort... huh... Oh, yeah...

Nate K said on August 29, 2006

Hmm. I dont know which one is better than the other, but I am more accustomed to using 'new'. However, I was wonering the same thing when I watched his screencast yesterday.

Time to go do some research.

Joe said on August 29, 2006

i think "new" is probably easier to read, since it alludes to a new object better than (), which may be easy to miss, especially if it's a big function with lots of lines.

Anthony said on August 29, 2006

I'm with Joe and y'self, 'new' gives you further hints to the object when you're scanning the page of code. But I will be reading the aforementioned article to find out just what the performance loss is.

Andrew Dupont said on August 29, 2006

"I don't use the "new". Apparently, function expressions are faster because they don't have to be parsed every time they are evaluated as is the case when you use the constructor form (new Function())."

This is not what Jon is talking about.

The Function constructor is slower, to be sure, because it takes a code string and evaluates it into a function. But what he's talking about is doing new function() { /* stuff */ } — instantiating an anonymous function.

Naturally, this is confusing.

nuffGigs said on August 29, 2006

I use "var obj = function(){...}" . Works fine for me.

Dustin's appoarch may help with private functions and vars. Check out this article on creating private static object members.

Jonathan Snook said on August 29, 2006

nuffGigs: var obj = function(){...} is just for assigning an anonymous function to a variable. Good for creating object classes. In the examples above, both are used to create singletons and both can be used to create private static object members.

In my preferred approach, I don't have to return an object and I still have a valid object. In Dustin's approach, if he doesn't return an object, then he gets 'undefined'. I also think my approach is easier to read. With Dustin's, it'd be easy to miss the ( ) brackets at the end of the function. I just wanted to see what others thought.

Dustin Diaz said on August 29, 2006

To be quite frank, I'm not even sure they're the same. Indeed, they both have their pros (the cons would just be what the other has a pro in).

So to put things in perspective, using the modular pattern (which is the self-invoking method) has the clear benefit of keeping things private. In any case, they're both singletons.

Thomas Messier said on August 29, 2006

@Andrew: Yeah, I noticed after that I'd missed the point, didn't see the () after the function. And I'd actually asked myself the same about Dustin's method and posted on his blog about it. I guess if you need to keep some variables out of the global scope using Dustin's way is better, otherwise you can just stick to the "regular" way.

Jonathan Snook said on August 29, 2006

Dustin: just to clarify, in both yours and mine, by returning an object, anything else defined within the function is still private.

Dustin Diaz said on August 30, 2006

FYI: This is the third time I've had to try posting this (your live preview crashes FF 1.5 when I try to insert code with 'pre' tags (I've temporarily disabled js to post this)).
------
Anyway, Jonathan, that is true. The modular pattern returns expandos though. In one sense, it really does serve an entirely different purpose. Eg: To get this:

var foo = function() {
  var bla = 'huzza';
  return {
    bar : function() {
      // cod here
    },
    baz : function() {
      // code here
    }
  };
}();

You'd have to do this (without the self-invoking funcitonality).

var foo = function() {
  var bla = 'huzzah';
};
foo.bar = function() {
  // code here
};
foo.baz = function() {
    // code here
};

But even then, you still don't have equal access to 'bla' through 'bar' and 'baz'. So as I mentioned, they're almost too different to compare.

Bramus! said on August 31, 2006

Always have been using the former, didn't even know about the latter one (*blush*), but now that I see it, I think it can be handy in some situations, but not all (cfr. Dustin's comment: "they're almost too different to compare")

Oh yeah, Dustin, FX (1.5.0.6) doesn't crash here when using the pre tag ... maybe Jonathan already fixed it?

Olivier Mengu� said on September 12, 2006

The two syntax execute the function, but in different contexts. When the function is executed, the difference appears in the content of the this variable. Below I've linked to the Mozilla documentation for more details.

The "new context", is an object creation, a prototype instantiation. Inside the function, this refers to the newly created object.

However, when just executing a function (anonymous or not) outside a "new context", this is not defined and eventually refers to an external this variable (the Window object when in a browser environment).

Also, the return value is not used in the same way. Just try the two following URLs in the location area of your browser:

javascript:new function(){return 'Z';}
javascript:(function(){return 'Z';})()

With the former you get a new object (converted to "[object Object]" for the representation in your browser window) while the later gives "Z".

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.