"use strict" 仅对当前作用域生效,无法全局启用;需在每个函数内显式声明,否则静默错误仍存在,ESM默认严格,CommonJS需手动添加。

为什么 "use strict" 不能只写在文件顶部就完事
全局启用 "use strict" 看似一劳永逸,但实际会漏掉大量函数级静默错误。比如 with 语句、意外创建全局变量、重复参数名等行为,在非严格模式下完全不报错,而严格模式只对**当前作用域**生效——如果函数没显式声明,它就继续静默运行。
实操建议:
- 每个独立函数都加
"use strict",尤其动态生成的函数(如new Function()需额外传入) - 模块环境(ESM)默认启用严格模式,但 CommonJS 的
.cjs文件仍需手动加 - 避免在 IIFE 外层写
"use strict"后直接跟普通函数声明——那些函数不在严格作用域内
delete 操作符在严格模式下的报错边界
非严格模式下 delete obj.prop 对不可配置属性(如 Object.defineProperty(obj, 'x', { configurable: false }))返回 false 却不报错;严格模式则直接抛 TypeError。这能暴露你误删内置属性或冻结对象字段的问题。
常见踩坑点:
-
delete window.location在非严格模式返回false,严格模式报错——说明代码存在对宿主对象的危险假设 - 用
delete清理数组元素(delete arr[0])会留下empty槽位,严格模式虽不禁止,但配合for...in遍历时容易漏数据,这时报错反而是好事 - 注意 Babel 等工具可能移除
"use strict",导致测试通过但线上出问题
严格模式如何揪出 this 的隐式绑定漏洞
非严格模式下,独立函数调用时 this 指向 window(浏览器)或 global(Node.js),掩盖了上下文丢失问题;严格模式让 this 保持 undefined,立刻暴露未正确绑定的回调或方法提取场景。
典型触发场景:
-
setTimeout(obj.method, 100)中method内部访问this.xxx→ 严格模式下直接TypeError: Cannot read property 'xxx' of undefined - 箭头函数不受影响(本身不绑定
this),但普通函数作为事件处理器时,this为undefined能快速定位是否漏了.bind()或handleClick = () => {...} - 类方法未用
bind或属性初始化语法时,严格模式会让错误出现在调用点而非深层逻辑里
严格模式下 arguments 和 eval 的限制怎么帮定位问题
arguments.callee 和 arguments.caller 在严格模式被禁用,强制你改用命名函数表达式;eval 不再能修改外层变量作用域。这些不是“功能阉割”,而是堵住隐蔽的执行路径依赖。
实际收益:
- 递归函数若依赖
arguments.callee,启用严格模式后立即报错,倒逼你补上函数名——这对堆栈追踪和调试至关重要 -
eval('var x = 1')在非严格模式会泄漏x到当前作用域,严格模式下x仅存在于eval内部,避免污染和意外交互 - 某些压缩工具(如 Terser)在检测到严格模式后会更激进地优化变量名,反而让源码映射更准——前提是你的代码真正在严格模式下跑通
真正起作用的不是加了 "use strict" 这行字,而是它迫使你面对那些原本被 JavaScript 引擎默默吞掉的歧义和危险假设。最常被忽略的是:严格模式不会自动修复问题,它只是把延迟爆炸的定时炸弹变成立刻冒烟的引信——而你得习惯在冒烟时第一时间看懂烟是从哪根线飘出来的。










