210

I've been seeing this syntax on a few libraries now and I'm wondering what the benefit is. (note i'm well aware of closures and what the code is doing, I'm only concerned about the syntactical differences)

!function(){
  // do stuff
}();

As an alternative to the more common

(function(){
  // do stuff
})();

for self invoking anonymous functions.

I'm wondering a few things. First off, what is allowing the top example to actually work? Why is the bang necessary in order to make this statement syntactically correct? I'm told also that + works, and I'm sure some others, in place of !

Second, what is the benefit? All I can tell is that it saves a single character, but I can't imagine that's such a huge benefit to attract numerous adopters. Is there some other benefit I"m missing?

The only other difference I can see would be the return value of the self invoking function, but in both of these examples, we don't really care about the return value of the function since it's used only to create a closure. So can someone tell me why one might use the first syntax?

brad
  • 30,001
  • 27
  • 98
  • 151
  • Frameworks do like to save as many characters as they can that a minifier can't optimise. – alex Apr 29 '11 at 02:45
  • First benefit comes to my head is you can create a sandbox like, (function($){ ... })(jQuery); – J.S. Taylor Apr 29 '11 at 02:49
  • 2
    both examples achieve this. As mentioned, I understand what these functions are doing, i'm more interested in the syntactical differences – brad Apr 29 '11 at 02:52
  • @J.S. Taylor, I believe you misread the question, but perhaps I'm wrong about that... – JAAulde Apr 29 '11 at 02:53
  • 8
    I attribute it to the need, nee, requirement to be cute in a way that is more sophisticated than the previous crew. "Oh, those parenthetical heathens, we've got !!" – Jared Farrish Apr 29 '11 at 02:54
  • wow 13 votes in less than 30 mins? –  Apr 29 '11 at 03:10
  • 2
    I never knew about this, awesome. I like the `!` as it emphasizes it's being executed. – cdmckay Apr 29 '11 at 03:11
  • ya i feel pretty good about this question :) – brad Apr 29 '11 at 03:14
  • I understand you know what the code is doing, I'm linking this here for future reference. :) [1](http://stackoverflow.com/questions/3755606/what-does-the-exclamation-mark-do-before-the-function) [2](http://stackoverflow.com/questions/5422585/preceding-function-in-javascript/5422658#5422658) – Shaz Apr 29 '11 at 03:36

6 Answers6

101

Ideally you should be able to do all this simply as:

function(){
  // do stuff
}(); 

That means declare anonymous function and execute it. But that will not work due to specifics of JS grammar.

So shortest form of achieving this is to use some expression e.g. UnaryExpression (and so CallExpression):

!function(){
  // do stuff
}(); 

Or for the fun:

-function(){
  // do stuff
}(); 

Or:

+function(){
  // do stuff
}(); 

Or even:

~function(){
  // do stuff
  return 0;
}( );
c-smile
  • 24,546
  • 7
  • 54
  • 79
  • 3
    so then the *only* benefit terseness? – brad Apr 29 '11 at 03:15
  • 12
    I've added all the options above to the performance test at: http://jsperf.com/bang-function – Shaz Apr 29 '11 at 03:21
  • 5
    Expressiveness I would say. Speed does not really matter in such cases as it run once. – c-smile Apr 29 '11 at 03:21
  • 1
    Out of curiosity, I noticed that no bang and bang perform the fastest but somewhere in the evolution of Chrome at least, bang became faster than no bang. (Probably statistically insignificant but...) Is there a reason why? I don't know much about code beneath the hood but find it quite fascinating. – jmk2142 May 07 '14 at 01:09
  • Two of your unary operators can be interpreted as binary if a semicolon is missing. The first and last are the safest of those examples. –  Apr 01 '15 at 14:43
  • The performance test @Shaz performed are very interesting, the bang is faster than a paren-wrapped IIFE, and the tilde ~ is even faster. – lacy Nov 15 '17 at 04:08
78

In Javascript, a line beginning with function is expected to be a function statement and is supposed to look like

function doSomething() {
}

A self-invoking function like

function(){
  // do stuff
}();

doesn't fit that form (and will cause a syntax error at the first opening paren because there is no function name), so the brackets are used to delineate an anonymous function expression.

(function(){
  // do stuff
})();

But anything that creates an expression (as opposed to a function statement) will do, so hence the !. It's telling the interpreter that this is not a function statement. Other than that, operator precedence dictates that the function is invoked before the negation.

I wasn't aware of this convention, but if it becomes common it may contribute to readability. What I mean is that anybody reading the !function at the top of a large block of code will expect a self-invocation, the way we are conditioned already to expect the same when we see (function. Except that we will lose those annoying parentheses. I would expect that's the reason, as opposed to any savings in speed or character count.

brainjam
  • 18,180
  • 7
  • 49
  • 78
  • This "line beginning with function is expected..." looks quite fuzzy. What about this: `var foo = {CR/LF here} function bar() {}` – c-smile Oct 04 '13 at 16:10
47

Besides the things that were already said, the syntax with the ! is useful if you write javascript without semicolons:

var i = 1
!function(){
  console.log('ham')
}()

i = 2
(function(){
  console.log('cheese')
})()

The first example outputs 'ham' as expected, but the second will throw an error because the i = 2 statement isn't terminated due to the following parenthesis.

Also in concatenated javascript files you don't have to worry if the preceding code has missing semicolons. So no need for the common ;(function(){})(); to make sure your own won't break.

I know my answer is kind of late but i think it haven't been mentioned yet:)

Ry-
  • 199,309
  • 51
  • 404
  • 420
Smoe
  • 1,430
  • 13
  • 10
  • 6
    +1 for the tip and the memories...no one likes to write javascript without semicolons these days. – Pablo Grisafi Jan 17 '12 at 18:28
  • 4
    Twitter Bootstrap is all JS without semicolons, and it's pretty new... (sorry if the above comment was sarcastic in nature and I missed it). – brandwaffle Aug 29 '12 at 20:29
  • 2
    This is not actually true. Consider the following example: !function(){console.log("ham");}()!function(){console.log("cheese")}(); you get an error: "SyntaxError: Unexpected token !" – heavysixer Feb 02 '13 at 17:33
  • Yes, you are right. There's an error, if you put those on the same line. I didn't think about that. But, no concatenation script/lib I used so far does that. And when you minify&concat your files semicolons are added. So, honestly, I can't imagine a case where you'd run into that problem. On the other hand, it's 2am here and I might be ignorant:) – Smoe Feb 03 '13 at 01:28
6

For one thing, jsPerf shows that using ! (UnaryExpression's) are usually faster. Sometimes they come out to be equal, but when they aren't, I haven't seen the non-banged one triumph too much over the others yet: http://jsperf.com/bang-function

This was tested on the latest Ubuntu with the oldest (per say..) Chrome, version 8. So results may differ of course.

Edit: How about something crazy like delete?

delete function() {
   alert("Hi!"); 
}();

or void?

void function() {
   alert("Hi!"); 
}();
Shaz
  • 14,594
  • 3
  • 39
  • 57
  • interesting! I got about 50/50 though in Safari speed-wise, non-banged certainly held its own. I wonder if there's some theory to the potential speed differences? – brad Apr 29 '11 at 03:02
  • @brad Must be something to do with safari, if you look at the tests, most of the other browsers seem to be favoring `!`. But I'd also like to find a theory on this as well :) – Shaz Apr 29 '11 at 03:07
  • 3
    i like void because it is explicitly saying "i don't care about return value", and because it reminds me of conventions in other languages – code_monk Aug 20 '14 at 23:45
4

So, with negate "!" and all other unary operators like +,-,~, delete, void, a lot has been told, just to sum up:

!function(){
  alert("Hi!");
}(); 

Or

void function(){
  alert("Hi!");
}();

Or

delete function(){
  alert("Hi!");
}();

And a few more cases with binary operators for fun :)

1 > function() {
   alert("Hi!"); 
}();

Or

1 * function() {
   alert("Hi!"); 
}();

Or

1 >>> function() {
   alert("Hi!"); 
}();

Or even

1 == function() {
   alert("Hi!"); 
}();

Leaving the ternary for someone else guys :)

Community
  • 1
  • 1
Arman
  • 4,547
  • 3
  • 30
  • 33
4

As you can see here, the best way to do self-invoked methods in javascript is using:

(function(){}()); -> 76,827,475 ops/sec

!function(){}();  -> 69,699,155 ops/sec

(function(){})(); -> 69,564,370 ops/sec
Geku
  • 93
  • 1
  • 6
  • 2
    I doubt performance is the reason to use one syntax or the other. At 70M ops/sec, declaring the closure is going to be thousands times faster than the code inside anyway – Eloims Jan 20 '16 at 14:27