Skip to content

严格模式

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'

evalarguments 不能被重新赋值

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()

禁止使用 functionif 语句中声明

在严格模式下,不能在块级作用域(如 ifforwhile)中声明函数,否则会抛出 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 () {} // ✅ 正确
}

基于 MIT 许可发布