我在几个JavaScript库中看到过这种表示法:
/**
* Library XYZ
*/
;(function () {
// ... and so on
虽然我对“立即执行函数”的语法感到非常舒适
(function(){...})()
我想知道前导分号的作用是什么。我唯一能想到的是它是一种保险措施。也就是说,如果库嵌入到其他有错误的代码中,它可以作为“最后一个语句在此处结束”的减速带。
它还有其他功能吗?
我在几个JavaScript库中看到过这种表示法:
/**
* Library XYZ
*/
;(function () {
// ... and so on
虽然我对“立即执行函数”的语法感到非常舒适
(function(){...})()
我想知道前导分号的作用是什么。我唯一能想到的是它是一种保险措施。也就是说,如果库嵌入到其他有错误的代码中,它可以作为“最后一个语句在此处结束”的减速带。
它还有其他功能吗?
它允许您将多个JavaScript文件安全地连接成一个文件,作为一个HTTP请求更快地提供。
(function(){...})()(function(){...})()
。 - Aaron Digulla实际上,最好的答案已经在问题中给出了,因此我将在此澄清一下:
立即调用的函数表达式前面的主要;
是为了防止在将其连接到包含未正确终止的表达式;
的文件时出现错误。
最佳实践是结束您的表达式使用分号,但也要使用前导分号作为保障。
"\n"
替换为";\n"
则毫无意义。 - Val Kornea通常情况下,如果一个语句以 (、[、/、+ 或 - 开头,那么它有可能被解释为前一语句的延续。在实践中,以 /、+ 和 - 开头的语句非常罕见,但以 ( 和 [ 开头的语句并不少见,至少在某些 JavaScript 编程风格中是如此。一些程序员喜欢在这样的语句开头加上防御性分号,以便即使在修改其前面的语句并删除先前的终止分号时,它仍然可以正确运行:
var x = 0 // Semicolon omitted here
;[x,x+1,x+2].forEach(console.log) // Defensive ; keeps this statement separate
来源:
这被称为前置分号。
它的主要目的是保护自己免受前面未正确关闭的代码的影响,这可能会导致问题。分号将防止这种情况发生。如果前面的代码未正确关闭,那么我们的分号将纠正这种情况。如果它已经正确关闭,则我们的分号将是无害的,不会产生任何副作用。
一个简洁明了的答案是安全地连接多个JavaScript文件。使用分号不会引起问题。
假设您有多个函数:
IIFE 1
(function(){
// The rest of the code
})(); // Note it is an IIFE
IIFE 2
(function(){
// The rest of the code
})(); // Note it is also an IIFE
(function(){})()(function(){})()
但是,如果在函数前面加上分号,它会变成这样:
;(function(){})();(function(){})()
如果添加一个 ;
,它会确保任何表达式都被正确地终止。
示例2
假设你有一个带有变量的 JavaScript 文件:
var someVar = "myVar"
另一个包含一些函数的 JavaScript 文件:
(function(){})()
var someVar = "myVar"(function(){})() // It may give rise to an error
var someVar = "myVar";(function(){})()
当你压缩JavaScript代码时,效果很好。这可以防止意外的语法错误。