主题
严格模式
JavaScript 严格模式 ("use strict") 引入了一系列限制,以提高代码的安全性和执行效率,防止常见的错误。
开启严格模式
js
"use strict";
// ...
...
"use strict"
可以被放在函数体的开头。这样则可以只在该函数中启用严格模式。但通常人们会在整个脚本中启用严格模式。
js
;(function () {
'use strict'
// ...
})()
浏览器控制台
当你使用 开发者控制台 运行代码时,请注意它默认是不启动 use strict
的。如果需要开启,可以像这样:
js
'use strict'; <Shift+Enter 换行>
// ...你的代码
<按下 Enter 以运行>
它在大部分浏览器中都有效,像 Firefox 和 Chrome。如果依然不行,还是老老实实在代码中加上吧。
自动开启
现代 JavaScript 支持 “class” 和 “module”,它们会自动启用 use strict
。
常见限制
禁止意外创建全局变量
在非严格模式下,给一个未声明的变量赋值会自动创建一个全局变量。而在严格模式下,会抛出 ReferenceError
。
js
'use strict'
x = 10 // ❌ 报错:Uncaught ReferenceError: x is not defined
对象的只读属性不能被修改
严格模式下,不能给不可写(writable: false
)的属性赋值,否则会抛出 TypeError
。
js
'use strict'
let obj = Object.defineProperty({}, 'prop', { value: 42, writable: false })
obj.prop = 100 // ❌ 报错:Cannot assign to read only property 'prop'
禁止删除不可删除的属性
严格模式下,delete
不能删除 Object.defineProperty()
设置为 configurable: false
的属性,否则会抛出 TypeError
。
js
'use strict'
let obj = Object.defineProperty({}, 'prop', { value: 10, configurable: false })
delete obj.prop // ❌ 报错:Cannot delete property 'prop'
eval
和 arguments
不能被重新赋值
js
'use strict'
eval = 100 // ❌ 报错:Assignment to eval or arguments is not allowed
arguments = [] // ❌ 报错
with
语句被禁止
with
语句会影响作用域链,容易导致变量解析错误,因此严格模式下被禁用。
js
'use strict'
with (Math) {
// ❌ 报错:Strict mode code may not include a with statement
console.log(PI)
}
this
在全局作用域或普通函数中是 undefined
严格模式下,独立函数的 this
不是 window
,而是 undefined
,防止无意间修改全局对象。
js
'use strict'
function show() {
console.log(this) // ❌ undefined(非严格模式下是 window)
}
show()
在构造函数中,this
仍然是新对象实例,但如果忘记用 new
调用,会抛出 TypeError
。
js
'use strict'
function Person(name) {
this.name = name
}
Person('John') // ❌ 报错:Cannot set properties of undefined (setting 'name')
函数参数名不能重复
严格模式下,函数的参数名不能重复,否则会抛出 SyntaxError
。
js
'use strict'
function test(a, a) {
// ❌ 报错:Duplicate parameter name not allowed
return a
}
octal
语法被禁用
严格模式下,八进制字面量(如 010
代表 8
)被禁止,会抛出 SyntaxError
。
js
'use strict'
let num = 010 // ❌ 报错:Octal literals are not allowed
delete
不能删除变量或函数
在严格模式下,delete
只能用于对象的属性,不能用于变量或函数,否则会抛出 SyntaxError
。
js
'use strict'
let x = 10
delete x // ❌ 报错:Delete of an unqualified identifier in strict mode
arguments
对象的行为更严格
arguments
不再与函数参数动态绑定,即修改arguments
不会影响原参数。
js
'use strict'
function test(a) {
arguments[0] = 100
console.log(a) // ✅ 仍然是 10,而不是 100
}
test(10)
- 不能使用
arguments.callee
访问当前函数,会抛出TypeError
。
js
'use strict'
function test() {
console.log(arguments.callee) // ❌ 报错
}
test()
禁止使用 function
在 if
语句中声明
在严格模式下,不能在块级作用域(如 if
、for
、while
)中声明函数,否则会抛出 SyntaxError
。
js
'use strict'
if (true) {
function foo() {} // ❌ 报错:In strict mode, functions can only be declared at the top level or inside a block with function expression
}
✅ 正确的做法:使用函数表达式
js
'use strict'
if (true) {
let foo = function () {} // ✅ 正确
}