6

所以 ECMAScript 5 引入了一些与 ECMAScript 3 不兼容的地方。


示例

已经写了很多文章,说明在 ES5 严格模式下this === null || this === undefined是可能的:

"use strict";
(function () {
    alert(this); // null
}).call(null);

但是,该标准 真正建议的是 ES5 引擎也允许在非严格模式下这样做:

15.3.4.3 ... thisArg 值未经修改作为this值传递。这是对第 3 版的更改,其中 aundefinednullthisArg 被替换为全局对象,而 ToObject 应用于所有其他值,并且该结果作为this值传递。

目前,IE9 是唯一真正以这种方式实现 ES5 的浏览器,事实证明这可能会破坏当前的脚本。伟大的。


ES5 规范的 Annix E列出了许多其他不兼容性。

那么,确保我们久经考验的 ES3 脚本能够继续完美运行的最佳方法是什么?某种自动化测试套件?我们必须手动测试吗?

4

2 回答 2

6

作为记录,提问者对 ES5 15.3.4.3 的解释是不正确的。在 ES5 中对非严格函数的任何调用都应该与 ES3 中的相同。全局对象仍被传递给任何以 null 或 undefined 作为 this 值调用的非严格函数。

分析中缺少的部分是10.4.3“输入功能代码”:

当控制进入函数对象F中包含的函数代码的执行上下文时,将执行以下步骤,调用者提供thisArg和调用者提供argumentsList

  1. 如果函数代码是严格代码,则将 ThisBinding 设置为thisArg
  2. 否则,如果thisArgnullundefined,则将 ThisBinding 设置为全局对象。
  3. ...

ES3 指定调用者负责将全局对象替换为 null 或未定义的 this 值。ES5 指定被调用者具有该责任(如果它不是严格模式函数)。对于非严格代码,这不是可观察到的差异。只有当被调用者是严格函数时,规范更改才会产生影响。

于 2012-02-17T20:14:19.823 回答
4

自动化测试套件当然是个好主意。

由于现在越来越多的实现实现了 ES5,因此在较新的浏览器中为您的脚本/库/应用程序运行测试套件是确保兼容性的好方法。

我有一个ES5 兼容性表,列出了一些更流行的实现的支持级别。它并不详尽,但它显示了总体方向——最新的 IE、WebKit、Chrome 和 Firefox 都具有很好的 ES5 支持。对于完整的一致性测试,您始终可以运行官方的 ES5 测试套件(为了方便起见,我在网上提供它)。

如果没有测试套件(它应该确实存在,因为它非常有用,因为其他几个原因),您可以在一个较新的(符合 ES5 的)实现中运行脚本/库/应用程序,看看哪些有效,哪些失败。

查阅附录 E是另一种方法。请注意,尽管列表看起来很大,但它并没有看起来那么糟糕。ES5 的目标之一是或多或少地从 ES3 过渡到无痛,将更激进的变化转移到opt-in strict mode的领域。

该列表中的许多兼容性更改可能会被忽视。以 15.1.1 中的更改为例,其中 global和undefined现在是只读的。考虑到正常的应用程序不会重新分配这些全局属性——除非是错误的——这种变化更像是一个令人愉快的“错误捕捉器”而不是“应用程序破坏者”。NaNInfinity

15.10.2.12 中的另一个可能是无辜的变化,其中空白字符类 ( \s) 现在也匹配 <BOM> ( U+FEFF) 字符。考虑到当前实现中的所有偏差(即使是关于 ES3),这种变化可能在大多数应用程序中都不会被注意到。

但是,也有更危险的变化,例如 inparseInt以及如何不再将以 0 开头的字符串视为八进制值。parseInt('010')不应再产生8(尽管某些实现选择故意违反该行为)。而且,依靠parseInt没有第二个“基数”的论点从来都不是一个好习惯。因此,如果您的应用程序始终指定基数,则无需担心。

因此,请参阅附录 E,在较新的实现(最好是多个)中测试您的脚本,并遵循最佳实践。这是确保兼容性的好方法。

于 2010-10-22T17:16:56.663 回答