Seb*_*tto 1190 javascript function
!function () {}();
Run Code Online (Sandbox Code Playgroud)
Nei*_*eil 2018
JavaScript语法101.这是一个函数声明:
function foo() {}
Run Code Online (Sandbox Code Playgroud)
请注意,没有分号:这只是一个函数声明.您需要一个调用foo()
来实际运行该函数.
现在,当我们添加看似无害的感叹号时:!function foo() {}
它将它变成一个表达式.它现在是一个函数表达式.
在!
本身并不能调用该函数,当然,但我们现在可以把()
结尾:!function foo() {}()
它的优先级高于!
并立即调用函数.
所以作者正在做的是为每个函数表达式保存一个字节; 一种更易读的写作方式是:
(function(){})();
Run Code Online (Sandbox Code Playgroud)
最后,!
使表达式返回true.这是因为在默认情况下所有IIFE回报undefined
,这给我们留下了!undefined
这是true
.不是特别有用.
Mic*_*urr 360
功能:
function () {}
Run Code Online (Sandbox Code Playgroud)
什么都不返回(或未定义).
有时我们想在创建函数时调用函数.你可能想尝试这个:
function () {}()
Run Code Online (Sandbox Code Playgroud)
但它导致了一个SyntaxError
.
!
在函数之前使用运算符会将其视为表达式,因此我们可以调用它:
!function () {}()
Run Code Online (Sandbox Code Playgroud)
这也将返回与函数返回值相反的布尔值,在这种情况下true
,因为!undefined
是true
.如果您希望实际返回值是调用的结果,那么尝试这样做:
(function () {})()
Run Code Online (Sandbox Code Playgroud)
dmi*_*i3y 57
使用airbnb JavaScript指南!
上标记的函数调用是很有意义的
通常在单独的文件(也称为模块)上使用此技术的想法,后来得到连接.这里需要注意的是,文件应该通过将新文件放在新行的工具连接起来(这对于大多数concat工具来说无论如何都是常见的行为).在这种情况下,使用!
将有助于避免错误,如果以前连接的模块错过了尾随分号,但这将提供灵活性,以任何顺序放置它们,不用担心.
!function abc(){}();
!function bca(){}();
Run Code Online (Sandbox Code Playgroud)
将工作相同
!function abc(){}();
(function bca(){})();
Run Code Online (Sandbox Code Playgroud)
但保存两个字符和任意看起来更好.
顺便说一句任何的+
,-
,~
,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?
Run Code Online (Sandbox Code Playgroud)
但是如果你将IIFE模式用于一个文件,一个模块代码分离并使用concat工具进行优化(这使得一行一个文件工作),而不是构造
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Run Code Online (Sandbox Code Playgroud)
将执行安全的代码,与第一个代码示例相同.
这个会抛出错误导致JavaScript ASI无法完成其工作.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Run Code Online (Sandbox Code Playgroud)
关于一元运算符的一个注释,它们会做类似的工作,但仅限于它们不在第一个模块中使用的情况.因此,如果您无法完全控制连接顺序,那么它们就不那么安全了.
这有效:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Run Code Online (Sandbox Code Playgroud)
这不是:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Run Code Online (Sandbox Code Playgroud)
gil*_*ly3 28
它返回语句是否可以计算为false.例如:
!false // true
!true // false
!isValid() // is not valid
Run Code Online (Sandbox Code Playgroud)
您可以使用它两次将值强制为布尔值:
!!1 // true
!!0 // false
Run Code Online (Sandbox Code Playgroud)
所以,更直接地回答你的问题:
var myVar = !function(){ return false; }(); // myVar contains true
Run Code Online (Sandbox Code Playgroud)
编辑:它具有将函数声明更改为函数表达式的副作用.例如,以下代码无效,因为它被解释为缺少必需标识符(或函数名称)的函数声明:
function () { return false; }(); // syntax error
Run Code Online (Sandbox Code Playgroud)
感叹号使任何函数始终返回布尔值.最终值是函数返回的值的否定.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Run Code Online (Sandbox Code Playgroud)
!
在上面的例子中省略了一个SyntaxError.
function bool() { return true; }() // SyntaxError
Run Code Online (Sandbox Code Playgroud)
但是,实现这一目标的更好方法是:
(function bool() { return true; })() // true
Run Code Online (Sandbox Code Playgroud)
!是一个逻辑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
Run Code Online (Sandbox Code Playgroud)
其他有效的运营商......
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Run Code Online (Sandbox Code Playgroud)
联合运营商......
+!(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
Run Code Online (Sandbox Code Playgroud)
它是 IIFE(立即调用函数表达式)的另一种编写方式。
它的另一种写法——
(function( args ) {})()
Run Code Online (Sandbox Code Playgroud)
与...一样
!function ( args ) {}();
Run Code Online (Sandbox Code Playgroud)
小智 5
它只是为了在我们进行javascript缩小时保存一个字节的数据.
考虑下面的匿名函数
function (){}
Run Code Online (Sandbox Code Playgroud)
为了使上述作为自调用函数,我们通常会将上面的代码更改为
(function (){}())
Run Code Online (Sandbox Code Playgroud)
现在我们添加了两个额外的字符,(,)
除了()
在调用函数所需的函数末尾添加.在缩小的过程中,我们通常专注于减小文件大小.所以我们也可以把上面的函数写成
!function (){}()
Run Code Online (Sandbox Code Playgroud)
两者都是自调用函数,我们也保存一个字节.(,)
我们只使用了一个字符而不是2 个字符!