6

Possible Duplicate:
!function(){ }() vs (function(){ })()

So I was just reading through the source of the new Bootstrap (2.0) from Twitter and noticed that there is an exclamation mark before the self-invoking anonymous function. When I saw this I immediately thought "Oh crap, there's a new, better way to do this?".

See for yourself!

Anyways, what's the difference? There must be a reason for it because they use it consistently in all of their JavaScript plugins (for Bootstrap).

Another thing I noticed was the "use strict" right after this. I don't think it's related to my previous inquiry, but can anyone explain this?

Thanks!

Community
  • 1
  • 1
John
  • 3,866
  • 6
  • 33
  • 37

3 Answers3

14
function(){} ();

By itself (see Point's comment) isn't going to be valid, since

function() {}

is a function declaration. To invoke it immediately, you need to get the JavaScript engine to treat the function as an expression. People usually do this as either of

(function(){}) ();  //more common

(function(){} ()); // Papa Crockford's preference:

with

!function(){}();

simply being a shorthand version of the same thing.

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • +1 Though later isn't required but a good practice accoding to Doughlas Crackford :) – Sarfraz Jan 25 '12 at 17:50
  • @gdoron - and I'm capped now. Better get back to work :) – Adam Rackis Jan 25 '12 at 17:51
  • The first one is not valid if that's all there is, but if (for example) there's something like `x = ` before it then it's OK. – Pointy Jan 25 '12 at 17:52
  • Thanks! I also found this [article](http://www.wordsbyf.at/2011/10/31/i-dont-write-javascript/) written by the dude who wrote the Javascript for Bootstrap. – John Jan 25 '12 at 18:03
  • @Johnny - that's a great article, I'll have to save it. Though I don't think I'm a good enough developer to get away with leaving off semi-colons like that. You have to know the langauge inside out to know when that'll work, and when it'll bite you – Adam Rackis Jan 25 '12 at 18:10
  • Something else worth noting is `!function(){}()` throws a "suspicious code" warning in Google's closure compiler while `;(function(){})()` and `(function(){}())` do not. Interesting. – John Jan 25 '12 at 18:16
8

If you have 2 scripts:

script1.js:

(function(){

})()

script2.js:

(function(){

})()

And you concatenate them, you get:

(function(){

})()
(function(){

})()

This causes an error, while:

!function(){

}()
!function(){

}()

Doesn't.

Esailija
  • 138,174
  • 23
  • 272
  • 326
  • This is also the reason some scripts use a semicolon at the start: `;(function(){}())` – hugomg Jan 25 '12 at 17:57
  • 1
    So, would it by safe to say `;(function(){}())` and `!function(){}()` serve the same purpose? – John Jan 25 '12 at 18:04
  • The semicolon just ends the line. If you don't omit it, then it won't cause a problem. It does not serve the same purpose as `!function(){}();` – bryc Jul 07 '15 at 06:49
3

The ECMAScript Language Specification, section 12.4, says:

An ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.

So if you want an expression statement that executes an anonymous function, you have to work around this restriction. Adding a ! (which just negates the result of the function) makes it clear to the interpreter that it's not a function declaration, avoiding this ambiguity.

sth
  • 222,467
  • 53
  • 283
  • 367