主题
严格模式
严格模式通过 "use strict" 改变一部分 JavaScript 的执行规则,让一些原本会被悄悄忽略的问题,变成更明确的报错。
它的目标不是“让代码更难写”,而是减少历史包袱带来的歧义和隐式行为。
为什么会有严格模式
早期 JavaScript 为了兼容性,保留了不少宽松行为,例如:
- 给未声明变量赋值时悄悄创建全局变量
- 某些错误写法静默失败
this在普通函数调用中默认指向全局对象
严格模式的核心价值就是把这些“容易出错但不容易发现”的行为收紧。
如何开启
在脚本顶部开启
js
'use strict'
const name = 'Lee'当它出现在脚本顶部时,通常表示整个脚本都以严格模式运行。
在函数内部开启
js
function test() {
'use strict'
return 1
}这样只影响当前函数内部。
哪些场景会自动启用
现代 JavaScript 里有两类代码默认就是严格模式:
- ES Module
class
也就是说,在模块文件和类体里,通常不需要再额外写 "use strict"。
严格模式最常见的行为变化
不能意外创建全局变量
非严格模式下,下面这种写法可能会偷偷把变量挂到全局对象上:
js
count = 1严格模式下会直接报错:
js
'use strict'
count = 1 // ReferenceError这是严格模式最有价值的一点之一,因为它能更早暴露拼写错误和漏写声明的问题。
普通函数里的 this 不再默认指向全局对象
js
'use strict'
function show() {
console.log(this)
}
show() // undefined这能避免函数在无意间把数据写到全局对象上。
对只读属性赋值会报错
js
'use strict'
const obj = Object.defineProperty({}, 'name', {
value: 'Lee',
writable: false,
})
obj.name = 'Vfan' // TypeError非严格模式下,这类赋值很多时候只是静默失败。
删除非法目标会报错
js
'use strict'
const value = 1
// delete value // SyntaxErrordelete 只适合删除对象属性,不适合删除变量绑定。
with 被禁用
js
'use strict'
// with (Math) {
// console.log(PI)
// }with 会让变量解析变得不透明,因此严格模式直接禁止它。
某些历史遗留能力被收紧
例如:
- 不能给
eval、arguments重新赋值 - 参数名不能重复
arguments.callee不可用
这些限制的共同方向都是减少动态、模糊和难以优化的行为。
和 this 的关系尤其值得注意
严格模式最常被感知到的变化之一,就是 this 行为变得更“诚实”。
js
'use strict'
function Person(name) {
this.name = name
}
// Person('Lee') // TypeError在这里,如果忘记使用 new,this 不会退回到 window,而是直接暴露问题。
严格模式不等于现代 JavaScript 的全部
严格模式只是一组执行规则的收紧,并不代表:
- 自动获得模块能力
- 自动启用 TypeScript 式检查
- 自动修复所有语言陷阱
它只是让一些危险行为更早失败。
现在还需要手动写 "use strict" 吗
在现代前端项目里,很多文件本身就是模块,因此通常已经默认处于严格模式。
所以实际判断可以是:
- 如果代码是 ES Module,通常不需要再手写
- 如果是老脚本、内联脚本或历史代码,仍然可能需要显式写出
使用建议
- 写现代模块代码时,把“默认严格模式”当作常态理解即可。
- 阅读老代码时,如果看到一些宽松行为,要先判断当前是否处于严格模式。
- 当代码在严格模式下报错时,优先把它理解成“更早暴露真实问题”,而不是“模式太严格”。
- 不要依赖
with、隐式全局变量或arguments.callee这类历史能力。
