7

when looking at the minified Sizzle code, I noticed that it begins like this:

!function(a){//...

  }(window)

Why is there an exclamation point at the beginning?

I thought that ! was the not operator.

Thank you.

Edit:

Full Code.

james emanon
  • 11,185
  • 11
  • 56
  • 97
Progo
  • 3,452
  • 5
  • 27
  • 44
  • 2
    it IS the NOT operator. MInd to show the whole code? I guess this isn't a function declaration but rather an IIFE... – Johannes H. Feb 05 '14 at 03:51
  • 1
    Are you sure that it's not something like `!function(){...return bool;}()` – p.s.w.g Feb 05 '14 at 03:51
  • @p.s.w.g: it shouldn't return boolean – zerkms Feb 05 '14 at 03:53
  • Guess that's meant to be pseudo-code, but `true`or `false`would do better, yes. – Johannes H. Feb 05 '14 at 03:53
  • For context, the code is [on github](https://github.com/jquery/sizzle/blob/master/dist/sizzle.min.js). If you understand what minification does, then I wouldn't question seemingly obscure syntax. –  Feb 05 '14 at 03:54
  • I don't understand why this question got a down vote. – Progo Feb 05 '14 at 03:59
  • @progo wasn't me, but most likely because you dind't specify the full code and, additionally, left out the most important part at the end - and the downvoter didn'T return after the edits. – Johannes H. Feb 05 '14 at 04:05

2 Answers2

6
!function(a){/* ... */}();

Using an unary operator to invoke an IIFE is common practice. That's a common shorthand for:

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

or:

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

You can also substitute the not unary operator with any other unary operator:

-function(a){ /* ... */ }();
+function(a){ /* ... */ }();
/* ... etc. */
Alex
  • 34,899
  • 5
  • 77
  • 90
  • 1
    You mean `!function() {}()` doing `!function(){}` won't call it – megawac Feb 05 '14 at 03:57
  • yupp, you're missing the paranthesis at the end in your first line. – Johannes H. Feb 05 '14 at 03:58
  • It's worth pointing out the function doesn't have a name. –  Feb 05 '14 at 03:59
  • Looks like there's also a performance increase to using bang functions: http://jsperf.com/bang-function – carloserivera Feb 05 '14 at 03:59
  • @megawac right, meant to do that. thanks for pointing that out ... – Alex Feb 05 '14 at 04:00
  • 1
    @remyabel Closures usually don't have one, and almost never when used as an IIFE. Actually, `(function Name () { ; }) ()`isn't valid, the "normal" funciton statement (`function name () { ; }`) most people use is just a shortcut for `var name = function () { ; }`. – Johannes H. Feb 05 '14 at 04:01
  • @JohannesH.: Why shoudn't `(function Name () { ; }) ()` be valid? It is. – Felix Kling Feb 05 '14 at 04:14
  • It is? Oh, well, I must admit, I never tested it. It isn't something I'd considered usefull yet. Well, then ignore that part of my comment. Rest stays valid though ;) – Johannes H. Feb 05 '14 at 04:15
  • 7
    Please note that the `!` does not *invoke* the function. It's purpose is to make the parser treat the function definition like an expression, not a statement. – Felix Kling Feb 05 '14 at 04:15
  • @JohannesH.: For function expressions, the name is optional (that's why it's omitted most of the time), for function declarations it is mandatory. – Felix Kling Feb 05 '14 at 04:16
  • @FelixKling Good to know, thanks for elaborating. – Johannes H. Feb 05 '14 at 04:17
  • Hm. That does imply that `var func1 = function func2 () { ; }` assigns the function to `func1` as well as `func2`, and both are visible inside the current scope, doesn't it? – Johannes H. Feb 05 '14 at 04:18
  • 3
    @JohannesH.: In older IE versions it does (it's a bug). The specification dictates that the name of a function *expression* is only visible within the function itself. It's great for debugging and recursive functions. – Felix Kling Feb 05 '14 at 04:24
  • @JohannesH.: You're welcome! Good resource: http://kangax.github.io/nfe/ – Felix Kling Feb 05 '14 at 04:26
  • 1
    +1 But be wary of using the `+` and `-` operators for this since they're overloaded as binary operators as well. So if you omit a semicolon on the previous line, it can give an undesired result. The unary operators that are not overloaded are best, like `!`, `void`, `~`, etc. – cookie monster Mar 01 '14 at 16:20
4

gives a good explaination for function invocation https://github.com/airbnb/javascript/issues/44#issuecomment-13063933

!function () {}();

is equivalent to

(function(){})();

except the author is saving 1 byte of code.

In many cases, it's about saving bytes.

!function aaa(){}()
!function bbb(){}();

is the same as this:

!function aaa(){}()
;(function bbb(){})();

notice the ";" in that last bit. That is defensive, as it protects your code a bit from runaway js that might preceed it.

funny, I asked this same question some time ago:

Came across a convention I've never seen. What does it do? !function

great reference on it: What does the exclamation mark do before the function?

Community
  • 1
  • 1
james emanon
  • 11,185
  • 11
  • 56
  • 97
  • 1
    Just for reference: in other programming languages, similar things are common. In bash scripts for example, the "do nothing command" (`:`) is often used to evaluate variable expansions. – Johannes H. Feb 05 '14 at 04:03