如何确保ES3程序在ES5引擎中运行?

时间:2010-10-22 12:48:35

标签: javascript backwards-compatibility ecma262 ecmascript-5

因此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的更改,其中undefinednull thisArg将替换为全局对象,ToObject将应用于所有其他值,并且结果将作为this值传递。

目前,IE9是唯一以这种方式实际实现ES5的浏览器,事实证明这可能是break current scripts。大。


<{3}}的Annix E列出了许多其他不兼容性。

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

2 个答案:

答案 0 :(得分:6)

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

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

  

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

     
      
  1. 如果功能代码是严格代码,请将ThisBinding设置为 thisArg
  2.   
  3. 如果 thisArg null undefined ,则设置ThisBinding       到全球对象。
  4.   
  5. ...
  6.   

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,其中全局undefinedNaNInfinity现在是只读的。考虑到理智的应用程序不会重新分配这些全局属性 - 除了错误 - 这种变化更像是一个令人愉快的“错误捕获者”,而不是“app-breaker”。

另一个无辜的变化是在15.10.2.12,其中空白字符类(\s)现在也匹配&lt; BOM&gt; (U+FEFF)角色。考虑到当前实现中的all the deviations(即使在ES3方面),这种变化很可能在大多数应用程序中被忽视。

但是,还有更危险的更改,例如parseInt中的更改以及它如何不再将以0开头的字符串视为八进制值。 parseInt('010')不应再生成8(尽管某些实现选择了deliberately violate that behavior)。而且,依靠parseInt没有第二个“基数”论证从来都不是一个好习惯。因此,如果您的应用程序始终指定基数,则无需担心。

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