!function () {}();
! is a logical NOT operator, it's a boolean operator that will invert something to its opposite.
Although you can bypass the parentheses of the invoked function by using the BANG (!) before the function, it will still invert the return, which might not be what you wanted. As in the case of an IEFE, it would return undefined, which when inverted becomes the boolean true.
Instead, use the closing parenthesis and the BANG (!) if needed.
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
Other Operators that work...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Combined Operators...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
There is a good point for using !
for function invocation marked on airbnb JavaScript guide
Generally idea for using this technique on separate files (aka modules) which later get concatenated. The caveat here is that files supposed to be concatenated by tools which put the new file at the new line (which is anyway common behavior for most of concat tools). In that case, using !
will help to avoid error in if previously concatenated module missed trailing semicolon, and yet that will give the flexibility to put them in any order with no worry.
!function abc(){}();
!function bca(){}();
Will work the same as
!function abc(){}();
(function bca(){})();
but saves one character and arbitrary looks better.
And by the way any of +
,-
,~
,void
operators have the same effect, in terms of invoking the function, for sure if you have to use something to return from that function they would act differently.
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
but if you using IIFE patterns for one file one module code separation and using concat tool for optimization (which makes one line one file job), then construction
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Will do safe code execution, same as a very first code sample.
This one will throw error cause JavaScript ASI will not be able to do its work.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
One note regarding unary operators, they would do similar work, but only in case, they used not in the first module. So they are not so safe if you do not have total control over the concatenation order.
This works:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
This not:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
!
will negate (opposite) whatever you're expecting as a result, i.e if you have
var boy = true;
undefined
boy
true
!boy
false
when you call boy
, your result will be true
, but the moment you add the !
when calling boy
, i.e !boy
, your result will be false
. Which in other words you mean NotBoy, but this time it's basically a boolean result, either true
or false
.
That's the same thing that happens to the !function () {}();
expression, running only function () {}();
will flag you an error, but add !
right in front of your function () {}();
expression, makes it the opposite of the function () {}();
which should return you true
. Example can be seen below:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true