JavaScript Bang "!"函数与前导分号";"国际金融协会

JavaScript Bang "!" Functions vs Leading Semi-Colon ";" IIFEs

本文关键字:quot 国际金融 Bang 函数 JavaScript      更新时间:2023-09-26

airbind建议我这样做:

!function() {
  // ...
}();

因为:

这确保了如果一个格式错误的模块忘记包含final分号没有错误,在生产时,脚本得到连接。

bang允许我绕过语言的语法规则:

// Evaluated in Chromium 34 console.
function(){}(); // => SyntaxError: Unexpected token (
!function(){}(); // => true

当连接其他模块时,bang似乎会起作用:

!function(){}();function(){}(); // => SyntaxError: Unexpected token (
!function(){}();!function(){}(); // => true
(function(){}());!function(){}(); // => true

然而,它似乎实际上并不"安全",因为如果其他人在他的脚本末尾没有分号:

!function(){}()!function(){}(); // => SyntaxError: Unexpected token !
(function(){}())!function(){}(); // => SyntaxError: Unexpected token !

看起来前面加一个分号IIFE比较好。

;(function() {
  // ...
}());
!function(){}();(function(){}()); // => undefined
(function(){}());(function(){}()); // => undefined
!function(){}();;(function(){}()); // => undefined
(function(){}());;(function(){}()); // => undefined

我错过了什么吗?是否可以使用bang "!"函数或者以分号";"生命真的因为它们连接的方式而优越吗?

那里总是有iefe。是用圆括号括起来,还是用!作为前缀,这是您的选择,没有什么区别。您需要其中任何一个来强制将函数解析为表达式。见javascript函数leading bang !语法:

是否用;前缀整个结构以防止错误与编写不良的脚本连接(JavaScript库中的前导分号是做什么的?)是完全无关的。你可以根据需要混合使用:

 !function(){…}() // not safe for arbitrary concatenation
 (function(){…}()) // not safe for arbitrary concatenation either
;!function(){…}()
;(function(){…}())

然而,有一种情况下()!的连接确实有区别:如果两个脚本连接在一起,以便在中间有一个换行符,并且前者不以分号结束。这允许自动插入分号-当下一行以"砰"的一声开始时!

1 + 2             // script A
!function(){…}(); // script B
// works!
1 + 2              // script A
(function(){…}()); // script B
// runtime error: "2 is not a function" (or whatever the previous line ends in)

我们学到:总是用分号结束你的脚本。使用智能连接。如果需要防止愚蠢的连接,请使用分号开始脚本。

!实际上与在连接文件时防止丢失分号无关。它通常用于强制将以下函数定义计算为表达式,而不是声明

另一方面,前导分号结束任何可能出现在它之前的"open"表达式语句。

但是如果你遵循解释,如果!是该行的第一个字符,它似乎就足够了。显然,由于ASI, JS会在前面添加一个分号。然而,这似乎是一种更脆弱的方法,因为您可能无法完全控制模块的连接方式。使用分号绝对"更安全"。

实际上这也是可行的:

;!function() {
  // ...
}();
!function(){}()!function(){}(); // => SyntaxError: Unexpected token !
!function(){}();!function(){}(); // => true
(function(){}());!function(){}(); // => true
!function(){}();;!function(){}(); // => true
(function(){}());;!function(){}(); // => true

所以生命并不比bang函数好,正如我在问题的最后一段中漫不经心地假设的那样。无论您使用的是bang函数还是IIFE,在它们前面加一个分号都是一种很好的防御技术。