!function () {}();
!function () {}();
Answers:
JavaScript语法101。这是一个函数声明:
function foo() {}
请注意,这里没有分号:这只是一个函数声明。您需要调用foo()
才能实际运行该功能。
现在,当我们添加看似无害的感叹号时:!function foo() {}
它将它变成一个表达式。现在它是一个函数表达式。
该!
单独不会调用函数,当然,但我们现在可以把()
结尾:!function foo() {}()
它的优先级高于!
并立即调用函数。
因此,作者正在做的就是为每个函数表达式保存一个字节。更具可读性的书写方式是:
(function(){})();
最后,!
使表达式返回true。这是因为在默认情况下所有IIFE回报undefined
,这给我们留下了!undefined
这是true
。不是特别有用。
!
返回布尔值,我们都知道,但是您要说的重点是,它还将函数声明语句转换为函数表达式,以便可以立即调用该函数而无需将其放在括号中。并不明显,而且显然是编码人员的意图。
var foo =
断声明/表达含糊,你可以简单地写var foo = function(bar){}("baz");
等
功能:
function () {}
不返回任何值(或未定义)。
有时我们想在创建函数时立即调用它。您可能会尝试这样做:
function () {}()
但结果是SyntaxError
。
!
在函数之前使用运算符会使它被视为表达式,因此我们可以将其称为:
!function () {}()
在这种情况下true
,这也会返回与函数返回值相反的布尔值,因为!undefined
is true
。如果您希望实际的返回值是调用的结果,请尝试通过以下方式进行操作:
(function () {})()
!
是将函数声明转换为函数表达式,仅此而已。
!function
语法
!
在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*/}()
它返回该语句是否可以评估为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
var myVar = !function(){ return false; }()
可以省略!
像var myVar = function(){ return false; }()
和功能将正确执行和返回值将保持不变。
true
用!0
和false
用!1
。它保存2或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
感叹号使任何函数始终返回布尔值。
最终值是该函数返回的值的取反。
!function bool() { return false; }() // true
!function bool() { return true; }() // false
!
在上面的示例中将省略SyntaxError。
function bool() { return true; }() // SyntaxError
但是,实现此目的的更好方法是:
(function bool() { return true; })() // true
!
更改运行时解析函数的方式。它使运行时将函数视为函数表达式(而不是声明)。这样做是为了使开发人员能够立即使用()
语法调用该函数。!
还将自身(即取反)应用于调用函数表达式的结果。
!
将否定(相反)结果的期望值,即如果您有
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