JavaScript Bang“!”函数与领先的半冒号“;”IIFEs

问题描述 投票:3回答:3

Airbnd suggests我这样做:

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

因为:

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

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

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

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

!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

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

javascript function concatenation iife
3个回答
7
投票

你总是有IEFEs。无论是将它们用括号括起来还是用!作为前缀都是你的选择,并没有什么区别。您需要其中一个强制将函数解析为表达式。有关详细信息,请参阅javascript function leading bang ! syntax

是否使用;为整个构造添加前缀以防止与编写糟糕的脚本(What does the leading semicolon in JavaScript libraries do?)连接的错误完全不相关。您可以根据需要混合模式:

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

然而,有一个连接的情况,其中()!确实有所不同:如果连接两个脚本以便在它们之间存在换行符,并且前者不以分号结束。这确实允许automatic semicolon insertion to jump in - 当下一行开始爆炸!

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)

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


4
投票

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

另一方面,一个前导分号结束可能在它之前出现的任何“开放”表达式语句。

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


-2
投票

实际上这也有效:

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

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

所以IIFEs并不比bang函数更好,因为我在我的问题的最后一段中心不在焉地假设。无论你是使用爆炸功能还是IIFE,在他们面前使用领先的分号是一种很好的防御技术。

© www.soinside.com 2019 - 2024. All rights reserved.