JavaScript Bang "!" Functions Vs Leading Semi-Colon ";" IIFEs
Solution 1:
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.
Solution 2:
The !
has actually nothing to with protecting against missing semicolons when concatenating files. It's often used to enforce that the following function definition is evaluated as expression, not as declaration.
A leading semicolon on the other hand ends any "open" expression statement that might come before it.
But if you follow the explanation, it seems like !
would suffice if it's the first character in the line. Apparently JS would add a semicolon to the previous due to ASI. However, that seems to be a more fragile approach, since you might not be in total control over how the modules are concatenated. Using a semicolon is definitely "safer".
Solution 3:
Actually this works too:
;!function() {
// ...
}();
!function(){}()!function(){}(); // => SyntaxError: Unexpected token !
!function(){}();!function(){}(); // => true
(function(){}());!function(){}(); // => true
!function(){}();;!function(){}(); // => true
(function(){}());;!function(){}(); // => true
So IIFEs are no better than bang functions, as I absentmindedly-assumed in the last paragraph of my question. Regardless of whether you use a bang function or an IIFE, a leading semi-colon before them is a good defensive technique.
Post a Comment for "JavaScript Bang "!" Functions Vs Leading Semi-Colon ";" IIFEs"