严格模式通过禁止未声明变量的隐式创建从源头阻断挂载,但需配合模块化、ESLint检查及IIFE封装等工程措施才能彻底杜绝全局污染。

严格模式本身不直接“审查”挂载行为,但它通过改变语言规则,让意外挂载变得不可能——关键在于它禁止未声明变量的隐式创建,而挂载到 window 正是这种隐式行为的典型结果。
严格模式如何切断挂载链条
非严格模式下,写 api = fetchApi() 会自动变成 window.api = fetchApi();严格模式下,这行代码直接报 ReferenceError,根本不会执行赋值,自然也就没有挂载发生。这不是事后检查,而是从源头阻断。
- 所有未用
let、const或var声明就赋值的操作,一律报错 - 函数声明(
function foo() {})本身在模块或严格脚本中不会挂到window,但若在非模块普通脚本中,仍会挂载——所以单靠"use strict"不够,必须配合模块化或作用域隔离 -
this在顶层函数中为undefined,避免因this.xxx = val误写成window.xxx = val
真正起效的组合策略
仅加 "use strict" 不能杜绝挂载,需搭配现代加载方式:
- 使用
<script type="module">:ESM 自动启用严格模式,且顶层作用域天然隔离,let/const/function全部不挂window - 避免混合加载:第三方统计脚本、广告代码等仍用普通
<script>,它们不受严格模式约束,是当前主要污染源 - 禁用
eval动态赋值:严格模式下eval('x = 1')不会污染外层,但若在非严格上下文或绕过严格模式调用,仍有风险
识别并拦截常见挂载陷阱
以下写法看似无害,实则主动打开全局泄漏闸门:
-
window.api = fetchApi()或globalThis.utils = {}:显式挂载,严格模式不限制,但应避免 -
window.addEventListener('load', init)中init是未声明函数(如function init() {...}写在监听器后),在非模块脚本中仍会挂到window - 在非模块脚本中使用
var声明:虽不报错,但var声明仍会挂到window,建议统一用let/const
构建时加固建议
仅靠运行时规则不够,工程上需多层设防:
- ESLint 配置
no-implicit-globals和no-global-assign规则,提前拦截 - 打包工具(如 Webpack/Vite)默认以 ESM 方式处理入口,确保第三方库也通过
import加载而非 script 标签 - 对无法改造的老 SDK,用 IIFE 包裹并手动清理:
(function(){/* SDK 代码 */}).call({});,再删掉window.xxx

















