JavaScript Bang "!" Functions vs Leading Semi-Colon ";" IIFEs

concatenation, function, iife, javascript

Solution

You always have IEFEs there. Whether you wrap them in parenthesis or prefix them with a `!` is your choice, and doesn't make a difference. You need either one to force the function to be parsed as an expression. See javascript function leading bang ! syntax for details.

Whether you prefix that whole construct with a `;` to prevent errors from concatenation with poor-written scripts (What does the leading semicolon in JavaScript libraries do?) is totally unrelated. You can mix the patterns as you want:

 !function(){…}() // not safe for arbitrary concatenation
 (function(){…}()) // not safe for arbitrary concatenation either
;!function(){…}()
;(function(){…}())

However, there is one case of concatenation where `()` vs `!` does make a difference: if two scripts are concatenated so that there is a newline in between, and the former does not end in a semicolon. This does allow automatic semicolon insertion to jump in - when the next line does begin with a bang!

1 + 2             // script A
!function(){…}(); // script B
// works!

1 + 2              // script A
(function(){…}()); // script B
// runtime error: "2 is not a function" (or whatever the previous line ends in)

We learn: Always end your script with a semicolon. Use intelligent concatenation. Start your script with a semicolon if you need to be safe against dumb concatenation.

Problem

Airbnd suggests I do this: ``` !function() { // ... }(); ``` Because: This ensures that if a malformed module forgets to include a final semicolon there aren't errors in production when the scripts get concatenated. The bang allows me to work around the language's grammar rules: ``` // Evaluated in Chromium 34 console. function(){}(); // => SyntaxError: Unexpected token ( !function(){}(); // => true ``` And when concatenating other modules the bang seems to do the trick: ``` !function(){}();function(){}(); // => SyntaxError: Unexpected token ( !function(){}();!function(){}(); // => true (function(){}());!function(){}(); // => true ``` However it doesn't seem to actually be "safe," because if someone else doesn't have a semi-colon at the end of his script: ``` !function(){}()!function(){}(); // => SyntaxError: Unexpected token ! (function(){}())!function(){}(); // => SyntaxError: Unexpected token ! ``` It would appear that a leading semi-colon IIFE is better. ``` ;(function() { // ... }()); !function(){}();(function(){}()); // => undefined (function(){}());(function(){}()); // => undefined !function(){}();;(function(){}()); // => undefined (function(){}());;(function(){}()); // => undefined ``` Am I missing something? Is it actually acceptable to use bang "!" functions or are leading semi-colon ";" IIFEs truly superior because of the way they concatenate?

Original source

Related problems