25

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#

0

3 Answers 3

50

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:

Sign up to request clarification or add additional context in comments.

4 Comments

Interesting. When is a self-invoking anonymous function useful? How is it different from simply executing the statements inside?
I see. Thanks. Would be nice if Javascript supports scoping with just the braces (like in C++)
@netvope ECMAScript 6 (a.k.a. ES 2015) does support block level scope with the let and const declarations.
6

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.

11 Comments

Interesting technique...
"negating the result" is misleading, @Twisol's answer is more accurate
@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
@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.
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.
|
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.

1 Comment

It's not a quirk of syntax. It's just syntax.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.