62

I know this is silly, but there's any difference between this:

(function() {  
    var foo = 'bar';  
})();

and this?

(function() {  
    var foo = 'bar';  
}());

JSLint tells us to Move the invocation into the parens that contain the function, but I see no need to.

Edit: The answers are too cool. ~function, the JSHint alternative along with jQuery's preference for (/***/)(); and Crockford's explanation! I thought I was going to just get a "they're the same thing" kind of answer.
You guys decide the best one through upvotes and I tick it.

Camilo Martin
  • 37,236
  • 20
  • 111
  • 154
  • 2
    These two examples are very nearly the same but the `dog balls` version returns the result outside of the first set of parenthesis while the Crockford approved version returns it inside. This is rarely significant but it is a difference. – Okonomiyaki3000 Jan 26 '16 at 00:54
  • @Okonomiyaki3000 It is not a difference, unless you significally change it (i.e., adding more stuff inside the parenthesis). In fact, I presume `foo = (/***/)();` and `foo = (/***/());` may compile to the same bytecode. Consider how `(a + b) + (c + d)` would compile to the same as `a + (b + c) + d`. – Camilo Martin Jan 26 '16 at 02:16
  • Yes, `foo = (/***/)();` and `foo = (/***/());` are the same but `(foo = /***/)();` and `(foo = /***/)();` are not. And, yes, this is pedantic. There's probably never a very good reason to do this. – Okonomiyaki3000 Jan 29 '16 at 00:03
  • @Okonomiyaki3000 It isn't pedantic enough it seems, as I'm just about to point out the two examples you say to be dissimilar are, in fact, identical. – Camilo Martin Jan 30 '16 at 03:30
  • Indeed. There is a typo in the previous post. The two which are different are, in fact: `(foo = /***/)();` and `(foo = /***/());` – Okonomiyaki3000 Feb 09 '16 at 05:21

3 Answers3

48

There's no difference. Both are valid ways to get the JavaScript parser to treat your function as an expression instead of a declaration.

Note that + and ! will also work, and are sometimes used by minifiers to save a character of size:

+function() {  
    var foo = 'bar';  
}();

!function() {  
    var foo = 'bar';  
}();

EDIT

As @copy points out, for completeness, ~ and - will also work.

-function() {  
    var foo = 'bar';  
}();

~function() {  
    var foo = 'bar';  
}();
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • 14
    For the sake of completeness, `~` and `-` will also do this (all unary operators). `~` is the coolest way of course. – copy Jan 08 '12 at 00:53
  • 3
    Wow, +1 for that cryptic syntax! That's got to make some unsuspecting coders scratch their heads if they see it in production. Does it work cross-browser then? Is it in the spec? I can't understand why it works. – Camilo Martin Jan 08 '12 at 00:55
  • Wow, `-` and `+` look like Objective-C, even more so when you give the functions names. http://jsfiddle.net/minitech/ugA9K/ – Ry- Jan 08 '12 at 00:57
  • @CamiloMartin - The reason for using `()` or any of these unary operators is to force the interpreter to treat the function as an expression rather than a declaration. – David Harkness Jan 08 '12 at 01:48
  • @DavidHarkness Ah, I see. The interpreter evaluating the operand makes sense now. – Camilo Martin Jan 08 '12 at 02:05
  • 1
    @CamiloMartin - yeah, it's just a hack to get the interpreter to not think that it's a function **declaration** -- like `function() foo {} – Adam Rackis Jan 08 '12 at 02:07
  • I've found some more supported operators: http://jsfiddle.net/Gzrnu/ – Camilo Martin Jan 08 '12 at 06:08
  • @CamiloMartin - it looks like the rest of those operators require a second operand - `x * function() {}();` Still cool though – Adam Rackis Jan 08 '12 at 06:09
  • 2
    Yay, there's one unary operator you forgot! :D But it won't make it shorter or as clear. http://jsfiddle.net/minitech/WL8tU/1/ (Also @CamiloMartin; a binary operator you forgot.) – Ry- Jan 08 '12 at 15:54
  • @minitech - LOL - love the typeof example - that made me +1 your answer. And yeah, not really a reason in the world to use it - certainly not shorter – Adam Rackis Jan 08 '12 at 16:23
  • Yeah, I can just imagine seeing that on The Daily WTF someday :) (Also, you should probably just +1 the comment, my answer isn't exactly relevant to that!) – Ry- Jan 08 '12 at 16:34
  • 2
    Oh, and one more that's a little more clear is `void`, though I hate that keyword. (Just for a complete list.) http://jsfiddle.net/WL8tU/2/ – Ry- Jan 09 '12 at 03:15
  • Okay, question ticked. If you ever see these aberrations in production code on The Daily WTF someday, you know what caused it ;) – Camilo Martin Jan 09 '12 at 07:35
  • @minitech That link does not work. – QuentinUK Mar 22 '13 at 22:32
  • @QuentinUK: The jsFiddle one? Are you sure it’s not jsFiddle’s fault? (Append `/show`.) – Ry- Mar 23 '13 at 01:43
  • Not sure! But I think I'll stick to the (brackets()); – QuentinUK Mar 23 '13 at 15:52
  • `new function() { var foo = 'bar'; }();` Also works ;) – A1rPun Aug 27 '13 at 15:31
  • There is a difference in the logically looking syntax (i just had a weird case with a 3th party app), 2 quick examples mixed up with jquery: `jQuery(document).ready(function ($) { ... })(jQuery, window, document); // Bug of the plugin / wrongly written ` `jQuery(document).ready(function ($) { … }(jQuery, window, document));` The first one failed, it will give you this error in your js console: TypeError: jQuery(...).ready(...) is not a function (jQuery(document).ready(function($){... But the second one goes through without any problems. It's not exactly the same case as the ... – ioCron Jun 19 '16 at 03:39
  • conversation suggests, but it can make a difference in different scenarios, therefore i have to agree with Crockford, it just looks syntactically more correct to me = more universal / consistently to use. – ioCron Jun 19 '16 at 03:39
38

That JSLint violation exists because Douglas Crockford says that the outside-parentheses version looks like "dog balls".

You can hear him discuss it in this video:

I think that looks goofy, 'cause what we're talking about is the whole invocation, but we got these things hanging outside of it looking sorta like ... dog balls.

He suggests that the parentheses inside help the reader understand that the entire statement is a function expression rather than a declaration.

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
10

No, I don't believe there's any difference. I personally prefer the former (and jQuery et. al. seem to agree) but they both work identically in every engine I've tested.

Also, JSLint is a little too strict sometimes. JSHint might be a little better in that regard.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Oh, didn't knew about JSHint. Yes, only code written while testing with JSLint passes it, I never seem to be capable of avoiding errors before checking. – Camilo Martin Jan 08 '12 at 00:53