!function () {}();
答案 0 :(得分:1928)
JavaScript语法101.这是函数声明:
function foo() {}
请注意,没有分号:这只是一个函数声明。您需要一个调用foo()
来实际运行该函数。
现在,当我们添加看似无害的感叹号时,!function foo() {}
会将其转换为表达式。它现在是函数表达式。
当然,!
本身并不会调用该函数,但我们现在可以将()
放在最后:!function foo() {}()
,其优先级高于!
,立即调用该功能。
所以作者正在做的是为每个函数表达式保存一个字节;更可读的写作方式是:
(function(){})();
最后,!
使表达式返回true。这是因为默认情况下,所有IIFE返回undefined
,这使!undefined
为true
。{{1}}。不是特别有用。
答案 1 :(得分:353)
功能:
function () {}
不返回任何内容(或未定义)。
有时我们想在创建函数时调用函数。你可能想尝试这个:
function () {}()
但会产生SyntaxError
。
在函数之前使用!
运算符会将其视为表达式,因此我们可以调用它:
!function () {}()
这也将返回与函数返回值相反的布尔值,在本例中为true
,因为!undefined
为true
。如果您希望实际的返回值是调用的结果,那么尝试这样做:
(function () {})()
答案 2 :(得分:53)
将!
用于airbnb JavaScript guide上标记的函数调用是很有意义的
通常在单独的文件(也称为模块)上使用此技术的想法,后来得到连接。这里需要注意的是,文件应该被工具连接起来,这些工具将新文件放在新行(这对于大多数连接工具来说无论如何都是常见的行为)。在这种情况下,使用!
将有助于避免在先前连接的模块错过尾随分号时出错,但这样可以灵活地将它们置于任何顺序而不用担心。
!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 :(得分:28)
它返回语句是否可以计算为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
答案 4 :(得分:6)
感叹号使任何函数始终返回布尔值。最终值是函数返回值的否定。
!function bool() { return false; }() // true
!function bool() { return true; }() // false
在上面的例子中省略!
将是一个SyntaxError。
function bool() { return true; }() // SyntaxError
然而,实现这一目标的更好方法是:
(function bool() { return true; })() // true
答案 5 :(得分:5)
!是一个逻辑 NOT 运算符,它是一个布尔运算符,它会将某些内容反转到相反的位置。
虽然您可以在函数前使用 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
答案 6 :(得分:5)
它只是为了在我们进行javascript缩小时保存一个字节的数据。
考虑以下匿名函数
function (){}
要将上述内容作为自调用函数,我们通常会将上述代码更改为
(function (){}())
现在我们添加了两个额外的字符(,)
,除了在调用函数所需的函数末尾添加()
。在缩小的过程中,我们通常专注于减小文件大小。所以我们也可以将上面的函数写成
!function (){}()
两者都是自调用函数,我们也保存一个字节。我们只使用了一个字符(,)
!
答案 7 :(得分:2)
它编写IIFE的另一种方式(立即调用函数表达式)。
其他写作方式 -
(function( args ) {})()
与
相同!function ( args ) {}();
答案 8 :(得分:0)
!
会否定(反对)你所期望的结果,即如果你有
var boy = true;
undefined
boy
true
!boy
false
当您致电boy
时,您的结果将为true
,但是当您在致电!
时添加boy
,即!boy
时,您的结果将是false
。换句话说,你的意思是 NotBoy ,但这次它基本上是一个布尔结果,true
或false
。
与!function () {}();
表达式发生的情况相同,仅运行function () {}();
会标记错误,但在!
表达式前面添加function () {}();
,使它与function () {}();
相反,它应该返回true
。示例如下所示:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true
答案 9 :(得分:0)
让我们再保存一些其他字节!
(() => {})()
示例:
(() => {return "yeah"})()