JavaScript Bang"!" 功能与领先的半结肠";" IIFEs

Jac*_*son 3 javascript function concatenation iife

Airbnd建议我这样做:

!function() {
  // ...
}();
Run Code Online (Sandbox Code Playgroud)

因为:

这可确保如果格式错误的模块忘记包含最终分号,则在脚本连接时,生产中不会出现错误.

爆炸让我可以解决语言的语法规则:

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

当连接其他模块时,爆炸似乎可以解决问题:

!function(){}();function(){}(); // => SyntaxError: Unexpected token (
!function(){}();!function(){}(); // => true
(function(){}());!function(){}(); // => true
Run Code Online (Sandbox Code Playgroud)

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

!function(){}()!function(){}(); // => SyntaxError: Unexpected token !
(function(){}())!function(){}(); // => SyntaxError: Unexpected token !
Run Code Online (Sandbox Code Playgroud)

看起来领先的分号IIFE更好.

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

!function(){}();(function(){}()); // => undefined
(function(){}());(function(){}()); // => undefined
!function(){}();;(function(){}()); // => undefined
(function(){}());;(function(){}()); // => undefined
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?使用爆炸"!"实际上是可以接受的吗?功能或领先的分号";" IIFE因其连接方式真正优越吗?

Ber*_*rgi 7

你总是有IEFEs.无论是将它们包装在括号中还是用它们作为前缀,!都是您的选择,并没有什么区别.您需要其中一个强制将函数解析为表达式.看javascript函数领先爆炸!语法细节.

是否为整个构造添加前缀;以防止与编写不良脚本的连接错误(JavaScript库中的前导分号是什么?)完全不相关.您可以根据需要混合模式:

 !function(){…}() // not safe for arbitrary concatenation
 (function(){…}()) // not safe for arbitrary concatenation either
;!function(){…}()
;(function(){…}())
Run Code Online (Sandbox Code Playgroud)

但是,有一个连接的情况,其中()vs !确实有所不同:如果连接两个脚本以便在它们之间存在换行符,并且前者不以分号结尾.这确实允许自动分号插入 - 当下一行以爆炸开始时!

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)
Run Code Online (Sandbox Code Playgroud)

我们学习:始终用分号结束脚本.使用智能连接.如果您需要安全防止哑连接,请使用分号启动脚本.