Strict mode: Transitioning to strict mode

严格模式:转换到严格模式

ECMAScript 5引入了严格的模式,现在已经在所有主流浏览器(包括IE10)中实现。尽管使Web浏览器将代码解释为严格很容易(只需添加'use strict';源代码的顶部),但将现有代码转换为严格模式需要更多的工作。

本文旨在为开发人员提供指导。

逐渐过渡

严格模式的设计使其可以逐渐过渡到它。可以单独更改每个文件,甚至可以将代码转换为严格模式直至功能粒度。

从非严格到严格的差异

语法错误

添加'use strict';时,以下情况会SyntaxError在脚本执行前抛出一个:

  • 八进制语法 var n = 023;

这些错误是很好的,因为它们揭示了简单的错误或不好的做法。它们发生在代码运行之前。

新的运行时错误

JavaScript曾经在所执行操作的上下文中以静默方式失败是一个错误。在这种情况下,严格模式会抛出。如果你的代码库包含这样的情况,测试将是必要的,以确保没有任何损坏。再一次,它可能发生在函数粒度级别。

将值设置为未声明的变量

function f(x) { 'use strict'; var a = 12; b = a + x * 35; // error! } f(42

这用于更改全局对象上的值,这很少是预期的效果。如果您确实想为全局对象设置一个值,请将其作为参数传递并将其明确指定为属性:

var global = this; // in the top-level context, "this" always // refers to the global object function f(x) { 'use strict'; var a = 12; global.b = a + x * 35; } f(42

试图删除一个不可配置的属性

'use strict'; delete Object.prototype; // error!

在非严格的情况下,这会默默地失败,与用户的期望相矛盾。

Poisoned arguments and function properties

访问arguments.calleearguments.calleranyFunction.caller,或anyFunction.arguments引发在严格模式错误。唯一合法的用例是重用一个函数,如下所示:

// example taken from vanillajs: http://vanilla-js.com/ var s = document.getElementById('thing').style; s.opacity = 1; (function() { if ((s.opacity-=.1) < 0) s.display = 'none'; else setTimeout(arguments.callee, 40 })(

可以改写为:

'use strict'; var s = document.getElementById('thing').style; s.opacity = 1; (function fadeOut() { // name the function if((s.opacity-=.1) < 0) s.display = 'none'; else setTimeout(fadeOut, 40 // use the name of the function })(

语义差异

这些差异是非常微妙的差异。测试套件可能无法捕捉到这种微妙的差异。仔细检查你的代码库可能是必要的,以确保这些差异不会影响你的代码的语义。幸运的是,这种仔细的审查可以逐步向功能粒度进行。

this in function calls

在函数调用中f()this值是全局对象。在严格模式下,现在是undefined。当用callor 调用函数时apply,如果该值是原始值,则将该函数装入对象(或用于undefinedand 的全局对象null)中。在严格模式下,该值直接传递,无需转换或更换。

arguments 不会别名命名函数参数

在非严格模式下,修改arguments对象中的值会修改相应的命名参数。这使JavaScript引擎的优化变得复杂,并使代码更难阅读/理解。在严格模式下,arguments对象被创建并使用与命名参数相同的值进行初始化,但对arguments对象或命名参数的更改不会互相反映。

改成 eval

在严格的模式代码中,eval不会在调用它的作用域中创建新变量。另外,当然,在严格模式下,字符串将使用严格模式规则进行评估。需要进行彻底的测试以确保没有任何问题。如果你不需要它,不使用eval可能是另一个实用的解决方案。

Strictness-neutral code

将严格代码转换为严格模式的潜在“缺点”是在旧版浏览器中语义可能不同,这些浏览器不实现严格模式。在某些罕见的情况下(如错误连接或缩小),您的代码也可能无法在您编写和测试的模式下运行。以下是使代码严格中性的规则:

  • 严格编写代码并确保没有严格的错误(从上面的“新运行时错误”部分)被抛出。

Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.