34

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

If you look at the source code for KnockoutJS 2.1.0 you will see a code structure like this start on line 7:

!function(factory) { ... }(factoryDefinition);

The not operator causes this expression to evaluate to true rather than undefined, but why bother?

Community
  • 1
  • 1
CgodLEY
  • 994
  • 8
  • 16
  • Yes, it appears I have the same question as the "exclamation mark" question. Apologies, I didn't notice it in my search. – CgodLEY Aug 11 '12 at 15:47
  • @CgodLEY: StackOverflow's search doesn't do so well with punctuation and other symbols. Helps a bit to spell it out. –  Aug 11 '12 at 15:50
  • 1
    You use it to provoke immediate invocation of the function by making it look like an expression and not statement. – dakt Jul 07 '15 at 14:51

2 Answers2

58

This is a concise way to form an immediately executed function expression.

Traditionally, people have used these two forms

(function(){ }()); // Recommended by Crockford
(function(){ })(); // What most people use

If you try to just use

function(){ }(); // Syntax error

it will be a syntax error, because it is interpreted as a function declaration rather than an expression. This is why you would need to wrap the function in parentheses.

But if you put a unary operator before the function declaration, you don't have to add a cosing parentheses, and it chops off one character of the code, which is a (very) tiny performance benefit. There are several unary operators that can be used for this same purpose

!function(){ }();
~function(){ }(); 
-function(){ }(); 
+function(){ }(); 
Peter Olson
  • 139,199
  • 49
  • 202
  • 242
3

Because if you don't do something then it looks like a syntax error:

function(factory) { ... }(factoryDefinition);

Try it.

It's necessary to get the parser to a point where it expects an expression, so that the function keyword is recognized in that context. Otherwise, when the parser sees function as the first token in a statement, it expects a simple function declaration, and that can't be followed by a parenthesized argument list.

There are various alternatives, around each of which cluster various opinions.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • I tried the following expression on NodeJS and it seemed just fine, am I missing something? `function(message){console.log(message)}('hello');` result: `hello` – CgodLEY Aug 11 '12 at 15:39
  • @CgodLEY That doesn't work in my Node console... (The output is `...`) – Šime Vidas Aug 11 '12 at 15:41
  • No, Node gives me a syntax error. (In fact I get it at the open paren in the function declaration, because a function declaration without a function name is erroneous. – Pointy Aug 11 '12 at 15:42
  • Ah, I didn't put the semi-colon and that caused it to work somehow, try this: `function(message){console.log(message)}('hello')` – CgodLEY Aug 11 '12 at 15:43
  • 1
    @CgodLEY: You should probably consider that a bug in the REPL. It won't work in your normal code. –  Aug 11 '12 at 15:45
  • @amnotiam Yes, I'm not sure why it's working :) – CgodLEY Aug 11 '12 at 15:51
  • @Pointy Thank you for the answer. Looking back I think you understood why the problem was occurring but it didn't click for me until I saw some concrete examples of the various alternatives. – CgodLEY Aug 11 '12 at 15:54