【问题标题】:Why is 'use strict' usually after an IIFE (rather than at the top of a script)?为什么“使用严格”通常在 IIFE 之后(而不是在脚本顶部)?
【发布时间】:2026-02-01 19:15:01
【问题描述】:

我注意到use strict 似乎更常见,如下所示:

(function() {
  'use strict';
  ...

比这个:

'use strict';
(function() {
  ...

例如,vanilla JS implementation of TodoMVC 就是这样做的。

这是有原因的吗?

编辑:我知道整个文件与功能块的区别。 TodoMVC 是一个很好的例子来说明为什么这个位置对我来说很奇怪,因为它不依赖任何外部库,所以整个“与非严格的第三方合作”在这里并不适用。

【问题讨论】:

  • Javascript 脚本通常被连接并压缩成一个文件。前一种方法确保您限制use strict 的范围。

标签: javascript


【解决方案1】:

local 范围内声明它会强制浏览器在strict-mode 下考虑功能块。

您可以通过non-strict 观察IIFE 之外的其他代码


内部IIFE

(function() {
  "use strict";
  a = 100;
})();
b = 200;

对于整个脚本:

"use strict";
(function() {
  try {
    a = 100;
  } catch (e) {
    console.log(e + '');
  }

})();
b = 200;

正如docs 中强调的那样,

如果您对整个脚本使用strict 模式,则不可能盲目地连接不冲突的脚本。考虑将严格模式脚本与非严格模式脚本连接起来:整个连接看起来很严格!反之亦然:非严格加严格看起来是非严格的。严格模式脚本之间的连接很好,非严格模式脚本的连接很好。只有连接严格和非严格脚本是有问题的。因此建议您逐个功能启用严格模式(至少在过渡期间)。

您还可以采用将脚本的全部内容包装在一个函数中并让该外部函数使用严格模式的方法。这消除了连接问题,但这意味着您必须将任何全局变量显式导出到函数范围之外。

【讨论】:

  • 我认为文档中的第二段可能最接近标记。我的直觉是,这只是一个人们不会经常考虑的约定,但恰好是一个很好的做法。
【解决方案2】:

我猜这是因为即使多个 JS 文件作为构建步骤连接在一起,该放置也肯定会启用严格模式(以允许组织代码而不会因多个 HTTP 请求而降低性能)。在文件开头放置"use strict",这些文件可能存在问题:

foo.js
function doThing() {
    console.log("done");
}
main.js
"use strict";

(function() {
    document.getElementById('thingy').addEventListener("click", doThing);
})();

如果上述文件首先与foo.js 连接,则main.js 中的"use strict" 将无效。可以通过将"use strict" 放入函数中来避免这种可能性。

我不知道 JS 的串联有多常见,我不知道较新的 require 方法或 import 关键字是否可以让您将 "use strict" 放置在您想要的任何位置,但也许放置"use strict" 在函数内部流行起来,而简单的连接很流行,人们在使用了这么久后认为没有理由改变约定。

【讨论】:

    【解决方案3】:

    如果您使用:

    'use strict';
    (function() {
      ...
    

    它将use strict模式应用于所有文件。

    相反,当你在这样的函数中使用use strict 时:

    // Non-strict code...
    
    (function(){
      "use strict";
       ...
      // Define your library strictly...
    })();
    
    // Non-strict code... 
    

    如果您必须混合新旧代码,这可能会有所帮助。

    【讨论】:

      【解决方案4】:

      为什么要严格模式

      严格模式消除了某些从语言设计的角度来看不太理想的许可语言解析和执行特性。这些非严格模式语言特征被认为是向后兼容的默认行为。概要和详细信息显示在此处。

      并没有明确定义这些早期 Netscape 时代的旧语言特征何时以及是否会被弃用,或者严格模式是否会在某些时候成为跨浏览器的默认行为,但更严格的模式可能会产生更少歧义和风险的源代码.如果您希望在编码实践和代码库中提高可维护性、可移植性和可扩展性,那么严格模式是一个不错的选择。

      语法

      “使用严格”;

      声明范围

      的范围取决于您将声明放在函数内部还是外部,并适用于闭包范围内声明之后的所有语句。

      如果所有文件或流都已经与更严格的模式兼容或者可以轻松地做到这一点,那么在函数内使用声明是错误的方法。冗余是不必要的,因此建议将声明放在文件顶部或流的开头。

      有时只有部分功能符合更严格的规则。在这种情况下,声明的不太理想的函数范围可用于鼓励至少在已经遵守的函数中进行更精细的编码实践。


      注意对于那些来自"What's the benefit of using "function() 'use strict'” in every file?"的人

      你可以放置

      "use strict";
      

      在代码序列的顶部或函数内部,因此每个文件或每个函数只有一行代码。

      其他行代码在代码here中有其他用途。

      • 自调用函数
      • 工厂调用

      【讨论】: