【问题标题】:What does the leading semicolon in JavaScript libraries do?JavaScript 库中的前导分号有什么作用?
【发布时间】:2010-12-24 20:15:21
【问题描述】:

在几个 JavaScript 库中,我一开始就看到了这种表示法:

/**
 * Library XYZ
 */
;(function () {
  // ... and so on

虽然我对“立即执行的函数”语法非常满意

(function(){...})()

我想知道前导分号是干什么用的。我能想到的只是它是一种保险。也就是说,如果该库嵌入到其他有缺陷的代码中,它就会充当“最后一条语句最晚在此处结束”的减速带。

它还有其他功能吗?

【问题讨论】:

标签: javascript syntax


【解决方案1】:

它允许您安全地将多个 JavaScript 文件合并为一个,以便将其作为一个 HTTP 请求更快地提供服务。

【讨论】:

  • 但是,如果所有文件都被正确编码,那就没有必要了,不是吗?
  • 否:在你的例子中,你会得到(function(){...})()(function(){...})()
  • 我的意思是“编码正确”,每个库都以正确数量的尾随分号结尾...
  • 是的,Boldewyn,但事实并非如此。
  • 两个编码错误的文件将不适合仅仅因为第三个文件包含此脏修复。为什么连接器不能在结果中的文件之间添加额外的分号?
【解决方案2】:

问题中实际上给出了最佳答案,因此为了清楚起见,我将在此处写下来:

在立即调用的函数表达式前面的前导 ; 是为了防止在将文件附加到包含未以 ; 正确终止的表达式的文件时附加文件时出错。

最佳做法是用分号结束表达式,但也要使用前导分号作为保护措施。

【讨论】:

  • 如果你使用防御性分号,为什么还要用分号结束你的表达式?要么你利用分号出现在每一行的末尾,要么你使用防御性分号。两者都做会使人们错误地得出结论,认为有理由同时做两者。使用防御性分号的建议很好;将"\n" 的每个实例也替换为";\n" 的建议毫无意义。
  • @VladimirKornea:因为您并不总是只使用自己的库 :)
  • 因为你不能按照你的约定依赖别人的代码。防御性地编码,然后你就不必了。
  • @VladimirKornea 如果您愿意,您也可以将其视为防御性的——它可以防御并非总是以防御性分号开头的其他人的代码。
【解决方案3】:

一般来说,如果语句以 (、[、/、+ 或 - 开头,则它可能是 解释为之前声明的延续。以 /, +, 开头的语句 和 - 在实践中非常罕见,但以 ( 和 [ 开头的语句并不少见 至少在某些 JavaScript 编程风格中是这样。一些程序员喜欢 在任何此类声明的开头放置一个防御性分号,以便它将 即使之前的语句被修改并且之前的语句也能继续正常工作 终止分号已删除:

var x = 0 // Semicolon omitted here
;[x,x+1,x+2].forEach(console.log) // Defensive ; keeps this statement separate

来源:

JavaScript: The Definitive Guide, 6th edition

【讨论】:

    【解决方案4】:

    这称为前导分号。

    它的主要目的是保护自己免受前面不正确关闭的代码的影响,这可能会导致问题。分号将防止这种情况发生。如果前面的代码不正确地关闭,那么我们的分号将纠正这个问题。如果它被正确关闭,那么我们的分号将是无害的并且不会有副作用。

    【讨论】:

      【解决方案5】:

      一个简单的答案是安全地连接多个 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(){})()
      

      【讨论】:

        【解决方案6】:

        缩小 JavaScript 代码会很好。它可以防止意外的语法错误。

        【讨论】:

        • 像什么?分号对以下代码有任何意义吗?还是仅用于合并在实际库前面的假设错误代码?
        • 中,单独那个代码,没有什么特别的意义,但是当那个代码在其他代码中间并且你把它缩小到单行时,可能会出现意想不到的错误,比如(1)分号前几行缺少,(1)前一个也是函数,所以它会是()()()(),当出错时,很难调试,我们不能说它有错误,因为在缩小之前它运行良好。跨度>
        • 但是正确处理这个问题肯定是缩小器的责任。现在有问题的缩小器是常态吗?
        猜你喜欢
        • 1970-01-01
        • 2017-09-19
        相关资源
        最近更新 更多