24

Sorry for posting this but !function is not google-able and I did not find it in my JavaScript code.

Here is how Twitter uses it:

<a href="https://twitter.com/share" class="twitter-share-button" data-url="http://google.com" data-text="Google says">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

from https://twitter.com/about/resources/buttons#

Barka
  • 8,764
  • 15
  • 64
  • 91

3 Answers3

48

It is short-hand or alternative of self-invoking anonymous function:

(function(){
  // code
})();

Can be written:

!function(){
  // code
}();

You can also use + instead of !.

If you simply did:

function(){
  // code
}();

That will create problems, that's why you need to add ! before it which turns the function declaration into function expression.

Quoting docs, section 12.4:

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

To better understand the concept, you should check out:

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • Interesting. When is a self-invoking anonymous function useful? How is it different from simply executing the statements inside? – netvope Jun 26 '12 at 04:26
  • 1
    @netvope: See http://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript – Sarfraz Jun 26 '12 at 06:06
  • I see. Thanks. Would be nice if Javascript supports scoping with just the braces (like in C++) – netvope Jun 27 '12 at 07:15
  • 1
    @netvope ECMAScript 6 (a.k.a. ES 2015) does support block level scope with the `let` and `const` declarations. – Scott Marcus Oct 08 '17 at 15:23
5

they're negating the result, not the function itself:

!function( x ){ return x }( true );
!true
false

In reality, it's a slightly compressed form of:

(function(){}())

since it requires 1 less character. The reason it's needed is that you can't call a function declaration directly, e.g. this is invalid:

function(){}()

but adding the ! at the beginning turns it into a function expression and makes it work.

  • Interesting technique... – Šime Vidas Feb 13 '12 at 20:12
  • 1
    "negating the result" is misleading, @Twisol's answer is more accurate – Factor Mystic Feb 13 '12 at 20:14
  • @ŠimeVidas -- I have a feeling this is generated code looking for self-invoking function patterns since it does save 1 character :) –  Feb 13 '12 at 20:14
  • @FactorMystic -- I explained the same thing :) The OP is confused because they think it means "not function" –  Feb 13 '12 at 20:15
  • This is a good example of how the ! has two meanings. In this case, the ! should be interpreted as self-invoking function, not as negation. – downeyt Feb 24 '13 at 14:17
  • Oops, I meant to write more, but hit enter too soon. --- This is a good example of how the ! has two meanings. In this case, the ! is interpreted as self-invoking function, not as negation, since the return value of the function is thrown away. If the return value were used in a larger statement, then the ! would not be needed to self-invoke the method, so it is interpreted as negation. Both of these work and display different results. alert(function(x){return x}(true)) alert(!function(x){return x}(true)) – downeyt Feb 24 '13 at 14:29
  • Does anybody know if the parser actually evaluates the negation before throwing the result away? Is saving a single character the only reason to prefer this to wrapping the function in parens? – jrz Jul 09 '13 at 16:47
  • 1
    @Jonz -- Yes, it evaluates it before throwing it away, not like it's an expensive op. It also prevents errors from code that basically evaluates to: `(function(){})()(function(){})()` -- The lack of `;` in the middle of that means the 2nd function is passed to the result of the first. Not desired behavior usually and results in an error or really weird behavior. `!` or any binary op prevents this –  Jul 12 '13 at 07:38
  • 4
    @downeyt The `!` does not have two meanings. When the JS runtime sees `!` it knows that it can only mean (because there is only one meaning for `!`) logical negation and because of that, the JS runtime understands that you can only negate an expression, not a statement, so the remainder of the instruction is treated as such. In this usage, the result of the expression doesn't matter and is discarded. There is no dual-meaning. – Scott Marcus Oct 08 '17 at 15:26
  • Why are you replying to a 5 year old conversation? :/ –  Oct 09 '17 at 01:16
  • 1
    Because it's the right thing to do :-) . It is never too late to put something straight. If he hadn't corrected it, I would have. – ThomasH Aug 19 '20 at 13:13
3

It's usually used to work around a quirk in the JavaScript syntax. This gives a syntax error:

function() {
}();

It's read as a function declaration (like function foo () {}), rather than a function expression. So adding the ! before it, or wrapping it in parentheses, forces the parser to understand that it's an expression.

Twisol
  • 2,762
  • 1
  • 17
  • 17