因此ECMAScript 5引入了与ECMAScript 3的一些不兼容性。
示例:
Many articles已经写过,说明在ES5严格模式下this === null || this === undefined
可能 :
"use strict";
(function () {
alert(this); // null
}).call(null);
但是,the standard 确实建议的是ES5引擎也允许此采用非严格模式:
15.3.4.3 ... thisArg值未经修改即作为
this
值传递。这是对版本3的更改,其中undefined
或null
thisArg将替换为全局对象,ToObject将应用于所有其他值,并且结果将作为this
值传递。
目前,IE9是唯一以这种方式实际实现ES5的浏览器,事实证明这可能是break current scripts。大。
那么确保我们久经考验的ES3脚本能够完美运行的最佳方法是什么?某种自动化测试套件?我们必须手动测试吗?
答案 0 :(得分:6)
对于记录,提问者对ES5 15.3.4.3的解释是不正确的。在ES5中对非严格函数的任何调用都应该与ES3中的相同。全局对象仍然传递给任何非严格函数,该函数使用null或undefined作为此值调用。
分析的缺失部分是10.4.3“输入功能代码”:
当控制进入执行时,执行以下步骤 函数对象 F 中包含的函数代码的上下文,一个调用者 提供了 thisArg ,并且调用者提供了 argumentsList :
- 如果功能代码是严格代码,请将ThisBinding设置为 thisArg 。
- 如果 thisArg null 或 undefined ,则设置ThisBinding 到全球对象。
- ...
醇>
ES3指定调用者负责将全局对象替换为null或未定义此值。 ES5指定被调用者具有该责任(如果它不是严格模式函数)。对于非严格的代码,这不是可观察到的差异。当被调用者是严格函数时,规范更改只会产生差异。
答案 1 :(得分:4)
自动测试套件当然是个好主意。
由于越来越多的实现现在实现ES5 ,因此在较新的浏览器中运行脚本/库/应用程序的测试套件是确保兼容性的好方法。
我有一个ES5 compatibility table,列出了一些更受欢迎的实现的支持。它并非详尽无遗,但它显示了整体方向 - 最新的IE,WebKit,Chrome和Firefox都有非常好的ES5支持。对于完整的一致性测试,您可以随时运行官方ES5测试套件(为方便起见,我在线提供right here)。
如果没有测试套件(它应该存在,因为它由于其他一些原因非常有用),你可以在一个较新的(符合ES5的)实现中运行脚本/库/应用程序,看看哪些有效,哪些有用失败。
咨询Annex E是另一种方式。请注意,即使列表看起来很大,但它并没有看起来那么糟糕。 ES5的目标之一是从ES3过渡到或多或少无痛,将更激进的变化转移到选择加入严格模式领域。
该列表中的许多兼容性更改可能会被忽视。例如,更改为15.1.1,其中全局undefined
,NaN
和Infinity
现在是只读的。考虑到理智的应用程序不会重新分配这些全局属性 - 除了错误 - 这种变化更像是一个令人愉快的“错误捕获者”,而不是“app-breaker”。
另一个无辜的变化是在15.10.2.12,其中空白字符类(\s
)现在也匹配< BOM> (U+FEFF
)角色。考虑到当前实现中的all the deviations(即使在ES3方面),这种变化很可能在大多数应用程序中被忽视。
但是,还有更危险的更改,例如parseInt
中的更改以及它如何不再将以0开头的字符串视为八进制值。 parseInt('010')
不应再生成8
(尽管某些实现选择了deliberately violate that behavior)。而且,依靠parseInt
没有第二个“基数”论证从来都不是一个好习惯。因此,如果您的应用程序始终指定基数,则无需担心。
请参阅附件E,在较新的实施中测试您的脚本(最好是多个),遵循最佳实践。这是确保兼容性的好方法。