4

Possible Duplicate:
What does the exclamation mark do before the function?

I was looking through the Twitter Bootstrap JavaScript code and I noticed all their plugins are wrapped in negating self invoking functions.

I am aware that function ($) { ... }(window.jQuery); invokes the function immediately.

But what is the ! for?

Community
  • 1
  • 1
Hailwood
  • 89,623
  • 107
  • 270
  • 423
  • See : http://stackoverflow.com/questions/5827290/javascript-function-leading-bang-syntax – c-smile Nov 28 '12 at 03:52
  • `function ($) { ... }(window.jQuery);` ...does *not* invoke the function immediately. It introduces a SyntaxError, which is why you need the `!` *(or any operator that will cause the function to be interpreted as part of an expression)*. – I Hate Lazy Nov 28 '12 at 03:55
  • Yes, I forgot to take into account how I normally wrap it in (), which I now know is the same as ! – Hailwood Nov 28 '12 at 05:05

1 Answers1

7

1) if you just do:

function () { /* ... */ }();

You will get an error.
JS will not allow you to fire off a function declaration (because of a concept of "variable hoisting", which isn't technically correct, but is much easier for a lot of people to think about).
If you use declarative functions:

function myFunc () { /* ... */ }

The JS engine will create them in the scope you're in, before creating the variables of the scope -- even if the vars are all on the top and the functions are all on the bottom.

So when you write:

function myFunc () { /* ... */ }();

There's an error there, because the vars which don't even exist yet, in the current scope might be called inside, which is a guaranteed crash.

To further that, if you don't give your function-declaration a name:

function () { /* ... */ }

...then there's an error there, regardless, because you can't call the function yet, but you have no way of getting at it, because it doesn't have a name, and you didn't assign it to a variable.

Operators like () or + or ! -- anything which will force the engine to evaluate whatever comes next, will allow you to fire the function like:

+function () { /* ... */ }();

As long as there is no variable listening for a return statement, you're fine.

2) Additionally, in the case of !function () { /*...*/ }();, if that function doesn't have a return statement naturally, then it will return undefined.
The opposite of undefined is true when coerced in that way...

...so if you really, REALLY wanted, you could do something like:

var success = !function () { /* ... */ }();
if (success) { doStuff(); }
Norguard
  • 26,167
  • 5
  • 41
  • 49