!function () {}();
#1楼
感叹号使任何函数始终返回布尔值。 最终值是该函数返回的值的取反。
!function bool() { return false; }() // true
!function bool() { return true; }() // false
省略!
在上述示例中,将出现SyntaxError。
function bool() { return true; }() // SyntaxError
但是,实现此目的的更好方法是:
(function bool() { return true; })() // true
#2楼
有一个使用的好处!
在airbnb JavaScript指南上标记的函数调用
在单独的文件(也称为模块)上使用此技术的一般想法,这些文件随后会串联在一起。 需要注意的是,文件应该由将新文件放在新行的工具串联(无论如何,这对于大多数concat工具来说都是常见的行为)。 在这种情况下,请使用!
如果先前串联的模块遗漏了尾部分号,则将有助于避免错误,但是这将使您可以灵活地以任意顺序放置它们,而不必担心。
!function abc(){}();
!function bca(){}();
将与
!function abc(){}();
(function bca(){})();
但可以保留一个字符,并且任意显示效果更好。
而且,就调用该函数而言, +
, -
, ~
, void
运算符中的任何一个都具有相同的效果,以确保您是否必须使用某些东西来从该函数中返回,它们的动作会有所不同。
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?
但是,如果您将IIFE模式用于一个文件,则将一个模块代码分开,并使用concat工具进行优化(这将使一行完成一个文件的工作),
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
与第一个代码示例一样,将执行安全的代码执行。
这将引发错误,因为JavaScript ASI将无法执行其工作。
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
关于一元运算符的一个说明,他们会做类似的工作,但仅在万一情况下,它们不在第一个模块中使用。 因此,如果您不能完全控制串联顺序,它们就不太安全。
这有效:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
这不是:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
#3楼
! 是一个逻辑非运算符,它是一个布尔运算符,它将把某些东西反过来。
尽管您可以在函数前使用BANG (!)来绕过被调用函数的括号,但它仍将反转返回值,这可能不是您想要的。 就像IEFE一样,它会返回undefined ,当反转时,它变为布尔值true。
而是,如果需要,请使用右括号和BANG( ! )。
// 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
其他工作人员...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
组合运算符...
+!(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
#4楼
这是编写IIFE(立即调用函数表达式)的另一种方式。
另一种写作方式-
(function( args ) {})()
和...一样
!function ( args ) {}();
#5楼
它返回该语句是否可以评估为false。 例如:
!false // true
!true // false
!isValid() // is not valid
您可以使用它两次来将值强制转换为布尔值:
!!1 // true
!!0 // false
因此,要更直接地回答您的问题:
var myVar = !function(){ return false; }(); // myVar contains true
编辑:它具有将函数声明更改为函数表达式的副作用。 例如,以下代码无效,因为它被解释为缺少所需标识符 (或函数名 )的函数声明:
function () { return false; }(); // syntax error
#6楼
功能:
function () {}
不返回任何值(或未定义)。
有时我们想在创建函数时立即调用它。 您可能会尝试这样做:
function () {}()
但它会导致SyntaxError
。
使用!
函数将其视为表达式之前的运算符,因此我们可以将其称为:
!function () {}()
这还将返回与函数返回值相反的布尔值,在这种情况下为true
,因为!undefined
为true
。 如果您希望实际的返回值是调用的结果,请尝试通过以下方式进行操作:
(function () {})()
#7楼
当我们进行JavaScript压缩时,它只是为了保存数据字节。
考虑下面的匿名函数
function (){}
为了使上述代码成为自调用函数,我们通常将上述代码更改为
(function (){}())
现在(,)
除了在函数末尾添加()
(,)
之外,我们还添加了两个额外的字符(,)
,这是调用该函数所必需的。 在缩小过程中,我们通常着重于减小文件大小。 所以我们也可以将上面的函数写为
!function (){}()
两者仍然都是自调用函数,我们也保存了一个字节。 而不是2个字符(,)
我们只使用了一个字符!
#8楼
!
将否定(相反)结果的期望值,即如果您有
var boy = true;
undefined
boy
true
!boy
false
当您打电话给boy
,您的结果将是true
,但是当您添加!
当给boy
(也就是!boy
打电话时,您的结果将为false
。 换句话说,您的意思是NotBoy ,但这一次基本上是一个布尔结果,可以是true
或false
。
这与!function () {}();
发生的事情相同!function () {}();
表达式,仅运行function () {}();
将标记您一个错误,但是添加!
就在您的function () {}();
前面function () {}();
表达式,使其与function () {}();
相反function () {}();
这应该使您返回true
。 示例如下所示:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true
#9楼
让我们保存其他一些字节!
(() => {})()
例:
(() => {return "yeah"})()
#10楼
JavaScript语法101。这是一个函数声明 :
function foo() {}
请注意,这里没有分号:这只是一个函数声明 。 您需要一个调用foo()
才能实际运行该函数。
现在,当我们添加看似无害的感叹号: !function foo() {}
,它将变成一个表达式 。 现在它是一个函数表达式 。
!
当然,仅单独调用不会调用该函数,但是我们现在可以将()
放在最后: !function foo() {}()
优先级高于!
并立即调用该函数。
因此,作者正在做的就是为每个函数表达式保存一个字节。 更具可读性的书写方式是:
(function(){})();
最后, !
使表达式返回true。 这是因为默认情况下,所有IIFE返回的都是undefined
,这给我们留下!undefined
,它为true
。 不是特别有用。