控制台默认非严格模式,模块脚本自动启用严格模式且不可关闭;非严格模式下未声明赋值会隐式挂载到全局对象,严格模式下则抛出referenceerror,强制变量显式声明以保障模块封装性与代码健壮性。

因为在控制台默认运行在非严格模式下,而模块脚本(.mjs 或 type="module" 的 <script></script>)**自动启用严格模式**,且不可关闭。
控制台默认是非严格模式
浏览器开发者工具的控制台执行代码时,不带任何模式声明,默认按“宽松模式”(sloppy mode)运行。这时给未声明变量赋值,比如:
name = "Alice";
引擎会在全局对象(如 window)上自动创建一个同名属性,等价于 window.name = "Alice"。不会报错,但会污染全局作用域。
模块脚本强制启用严格模式
根据 ES 规范,所有 ESM 模块(包括通过 import 加载的脚本、<script type="module"></script>、或后缀为 .mjs 的文件)**隐式处于严格模式**,无需写 "use strict"。此时:
- 未声明就赋值(如
count = 10)直接抛出 ReferenceError - 变量必须显式用
let、const或var声明 - 无法隐式挂载到全局对象,
this在顶层也指向undefined
为什么这样设计
模块的目标是封装与可预测性。允许隐式全局变量会破坏模块边界,导致命名冲突、调试困难和意外副作用。强制声明变量能提前暴露错误,提升代码健壮性。
例如,在模块中写:
userEmail = "test@example.com";
会立刻报错:ReferenceError: userEmail is not defined,而不是悄悄创建一个全局变量,等到后期被其他模块误读才出问题。
验证方式很简单
在控制台输入:
console.log(this === window); // true(非严格)
在模块脚本中执行同样代码:
console.log(this === window); // false(严格模式下顶层 this 是 undefined)
这说明执行环境已切换,规则自然不同。











