使用'use strict';
不会突然让你的代码变得更好。
JavaScript 严格模式是ECMAScript 5中的一个特性。您可以通过在脚本/函数的顶部声明它来启用严格模式。
'use strict';
当 JavaScript 引擎看到这个指令时,它将开始以特殊模式解释代码。在这种模式下,当检测到某些可能最终成为潜在错误的编码实践时会引发错误(这是严格模式背后的原因)。
考虑这个例子:
var a = 365;
var b = 030;
由于痴迷于排列数字文字,开发人员无意中b
用八进制文字初始化了变量。非严格模式会将其解释为具有值的数字文字24
(以 10 为基数)。但是,严格模式会抛出错误。
有关严格模式下的非详尽专业列表,请参阅此答案。
我应该在哪里使用'use strict';
?
如何使用严格模式?
'use strict';
在脚本顶部插入一条语句:
// File: myscript.js
'use strict';
var a = 2;
....
请注意,文件中的所有内容都myscript.js
将在严格模式下进行解释。
'use strict';
或者,在函数体顶部插入一条语句:
function doSomething() {
'use strict';
...
}
函数词法范围内的所有内容都doSomething
将在严格模式下解释。词法作用域这个词在这里很重要。例如,如果您的strict代码调用了非 strict库的函数,则只有您的代码在严格模式下执行,而不是被调用的函数。请参阅此答案以获得更好的解释。
严格模式下禁止哪些事情?
我找到了一篇很好的文章,描述了严格模式下禁止的几件事(请注意,这不是一个详尽的列表):
范围
从历史上看,JavaScript 一直对函数的作用域感到困惑。有时它们似乎是静态作用域的,但某些特性使它们表现得像动态作用域一样。这是令人困惑的,使程序难以阅读和理解。误解会导致错误。这也是性能的问题。静态作用域允许变量绑定在编译时发生,但动态作用域的要求意味着绑定必须推迟到运行时,这会带来显着的性能损失。
严格模式要求所有变量绑定都是静态完成的。这意味着必须消除或修改以前需要动态绑定的功能。具体来说,取消了 with 语句,并且 eval 函数篡改其调用者环境的能力受到严格限制。
严格代码的好处之一是YUI Compressor之类的工具
在处理它时可以做得更好。
隐含的全局变量
JavaScript 有隐含的全局变量。如果您没有显式声明变量,则会为您隐式声明一个全局变量。这使初学者更容易编程,因为他们可以忽略一些基本的家务活。但它使大型程序的管理变得更加困难,并且大大降低了可靠性。所以在严格模式下,不再创建隐含的全局变量。您应该显式声明所有变量。
全球泄漏
有许多情况可能导致this
绑定到全局对象。例如,如果您new
在调用构造函数时忘记提供前缀,则构造函数this
将意外绑定到全局对象,因此它不会初始化新对象,而是会默默地篡改全局变量。在这些情况下,严格模式将改为绑定this
到undefined
,这将导致构造函数改为抛出异常,从而可以更快地检测到错误。
嘈杂的失败
JavaScript 一直都有只读属性,但在 ES5 的Object.createProperty
函数公开该功能之前,您无法自己创建它们。如果您尝试将值分配给只读属性,它将静默失败。赋值不会改变属性的值,但你的程序会继续进行,就好像它已经改变了一样。这是一种完整性风险,可能导致程序进入不一致的状态。在严格模式下,尝试更改只读属性将引发异常。
八进制
在字长为 3 的倍数的机器上进行机器级编程时,数字的八进制(或以 8 为基数)表示非常有用。在使用字长为 60 位的 CDC 6600 大型机时需要八进制。如果您可以阅读八进制,您可以将一个单词视为 20 位数字。两位代表操作码,一位代表 8 个寄存器之一。在从机器代码缓慢过渡到高级语言的过程中,人们认为在编程语言中提供八进制形式是有用的。
在 C 中,选择了一个非常不幸的八进制表示:前导零。所以在 C 中,0100
表示 64,而不是 100,并且08
是错误,而不是 8。更不幸的是,这种不合时宜的现象已被复制到几乎所有现代语言中,包括 JavaScript,它仅用于创建错误。它没有其他目的。所以在严格模式下,八进制形式不再被允许。
等等
arguments 伪数组在 ES5 中变得更像数组了。在严格模式下,它会失去其callee
和caller
属性。这使得您可以在arguments
不放弃大量机密上下文的情况下将您的代码传递给不受信任的代码。此外,
arguments
还消除了函数的属性。
在严格模式下,函数字面量中的重复键会产生语法错误。一个函数不能有两个同名的参数。函数不能有与其参数之一同名的变量。函数不能delete
拥有自己的变量。对不可配置属性的尝试
delete
现在会引发异常。原始值不是隐式包装的。
未来 JavaScript 版本的保留字
ECMAScript 5 添加了保留字列表。如果将它们用作变量或参数,严格模式将引发错误。保留字是:
implements
, interface
, let
, package
, private
, protected
, public
, static
, 和yield
延伸阅读