logo
Published on

JavaScript中的'use strict'作用及其原理

Authors
  • Name
    Twitter

JavaScript严格模式(strict mode)是ECMAScript 5中的一项特性。通过在脚本或函数顶部声明'use strict';,可以启用严格模式。

'use strict'

当JavaScript引擎看到这个指令时,就会以一种特殊的模式解析代码。在这种模式下,当遇到某些可能导致潜在错误的编码实践时,会抛出错误。启用严格模式的初衷正是为了捕捉这些潜在的错误。

例子

var a = 365
var b = 030

在这个例子中,开发者可能因为对齐数值字面量而无意中用八进制字面量初始化了变量b。在非严格模式下,这会被解释为值为24(十进制)数字。然而,在严格模式下,这样做会抛出错误。

一个更详细的严格模式特性的列表可以参考这个回答

什么情况下应该使用 'use strict';?

在新的JavaScript应用中

绝对应该使用! 严格模式可以在你编写代码时帮助你发现一些潜在的问题。

在已有的JavaScript代码中

可能不适合! 如果你的现有JavaScript代码包含严格模式下禁止的语句,应用程序将会直接崩溃。如果你想启用严格模式,那么你需要准备好调试并修正现有的代码。这就是为什么“使用'use strict';不会立刻让代码变得更好”的原因。

如何使用严格模式?

在脚本文件顶部插入 'use strict'; 声明

// 文件: myscript.js
'use strict'
var a = 2
// 其他代码

注意,文件myscript.js中的所有代码都会在严格模式下解释。

在函数体顶部插入 'use strict'; 声明

function doSomething() {
  'use strict'
  // 函数体中的代码
}

函数doSomething的词法范围内的所有代码都会在严格模式下解释。词法范围非常重要,例如,如果你的严格模式代码调用了一个非严格模式的库函数,只有你的代码在严格模式下执行,而被调用的函数不会。

更多详细解释可以参考这个回答

严格模式下禁止的行为

找到了一篇不错的文章描述了一些在严格模式下被禁止的行为(注意这不是一个详尽的列表):

作用域

JavaScript在函数作用域的问题上一直存在困扰。有些情况下是静态作用域,但有些特性让它们表现得像动态作用域。这导致了困惑和bug。严格模式要求所有的变量绑定必须静态完成,也就是限制或修改以前需要动态绑定的特性。具体来说,with语句被移除,eval函数的能力被严格控制。

隐式全局变量

JavaScript有隐式全局变量。如果你没有显式声明变量,系统会为你隐式声明一个全局变量。这对初学者来说很方便,但对大型程序的管理极其不利。在严格模式下,隐式全局变量不再存在。所有变量必须显式声明。

全局泄漏

有一些情况可能会导致this绑定到全局对象。在严格模式下,这会被绑定到undefined,从而引发异常。

无声失败

如果你试图给只读属性赋值,非严格模式下会静默失败,而严格模式会抛出异常。

八进制数

在严格模式下,八进制数不再被允许。

其他

  • arguments伪数组在ES5中变得更像真正的数组,并失去了calleecaller属性。
  • 函数不能有重复的参数名。
  • 不能删除变量或不可配置的属性。
  • 原始值不再被隐式包装。

为未来的JavaScript版本保留的关键词

ECMAScript 5增加了一些保留字。如果使用这些保留字作为变量或参数名,严格模式下会抛出错误。保留字有:

implements, interface, let, package, private, protected, public, static, 和 yield

进一步阅读