Как убедиться, что программы ES3 будут работать в движке ES5? - PullRequest
5 голосов
/ 22 октября 2010

Итак, ECMAScript 5 вводит некоторые несовместимости с ECMAScript 3.


Пример :

Множество статей было написано, что this === null || this === undefined возможно в строгом режиме ES5 :

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

Но то, что стандарт на самом деле предполагаетчто ядра ES5 также допускают это в нестрогом режиме :

15.3.4.3 ... Значение thisArg передается без изменений как значение this.Это изменение по сравнению с выпуском 3, где undefined или null thisArg заменяется глобальным объектом, а ToObject применяется ко всем другим значениям, и этот результат передается как значение this.

В настоящее время IE9 является единственным браузером, который действительно реализует ES5 таким образом, и оказывается, что это может сломать текущие сценарии .Отлично.


Annix E из ES5 spec перечисляет десятки других несовместимостей.

Так что лучший способ убедиться, что наши проверенные скрипты ES3 будутпродолжать работать без нареканий?Какой-то автоматический тестовый набор?Придется ли проверять все вручную?

Ответы [ 2 ]

6 голосов
/ 18 февраля 2012

Для записи, интерпретатор ES5 15.3.4.3 не отвечает.Любой вызов нестрогой функции в ES5 должен быть таким же, как в ES3.Глобальный объект все еще передается в любую нестрогую функцию, которая вызывается со значением null или undefined в качестве значения this.

Отсутствует фрагмент анализа 10.4.3 «Ввод кода функции»:

Следующие шаги выполняются, когда элемент управления входит в контекст выполнения для кода функции, содержащегося в объекте функции F , предоставлен вызывающий объект thisArg и предоставлен вызывающий элемент argumentsList :

  1. Если код функции является строгим кодом, установите для ThisBinding значение thisArg .
  2. Иначе, если thisArg равно null или undefined , установите ThisBinding для глобального объекта.
  3. ...

ES3 указал, что вызывающая сторонабыл ответственным за замену глобального объекта нулевым или неопределенным этим значением.ES5 указывает, что вызываемый имеет такую ​​ответственность (если это не функция строгого режима).Для нестрогого кода это не является заметной разницей.Изменение спецификации имеет значение только тогда, когда вызываемый объект является строгой функцией.

4 голосов
/ 22 октября 2010

Автоматизированный набор тестов, безусловно, хорошая идея.

Поскольку все больше и больше реализаций внедряют ES5 , запуск набора тестов для вашего скрипта / библиотеки / приложения в новых браузерах является хорошим способом обеспечения совместимости.

У меня есть таблица совместимости ES5 , в которой указан уровень поддержки некоторых наиболее популярных реализаций. Он не исчерпывающий, но показывает общее направление - последние версии IE, WebKit, Chrome и Firefox имеют неплохую поддержку ES5. Для полного теста на соответствие вы всегда можете запустить официальный набор тестов ES5 (который для удобства доступен онлайн прямо здесь ).

Если нет набора тестов (который действительно должен существовать, поскольку он очень полезен по нескольким другим причинам), вы можете просто запустить скрипт / библиотеку / приложение в одной из более новых (соответствующих ES5) реализаций и посмотреть, что работает и что выходит из строя.

Консультации Приложение E - это еще один способ. Обратите внимание, что хотя список кажется довольно большим, он не так плох, как кажется. Одной из целей ES5 было сделать переход от ES3 более или менее безболезненным, перенеся более радикальные изменения в область opt-in строгого режима .

Многие изменения совместимости из этого списка, вероятно, останутся незамеченными. Возьмем, к примеру, изменение в 15.1.1, где глобальные undefined, NaN и Infinity теперь доступны только для чтения. Учитывая, что вменяемые приложения не переназначают эти глобальные свойства - за исключением по ошибке - это изменение больше похоже на "ловушку ошибок", чем на "app-breaker".

Еще одно невинное изменение в версии 15.10.2.12, где класс пробельных символов (\s) теперь также соответствует символу (U+FEFF). Учитывая все отклонения в текущих реализациях (даже в отношении ES3), это изменение, вероятно, останется незамеченным в большинстве приложений.

Однако есть также более опасных изменений , таких как изменения в parseInt и то, как он больше не обрабатывает строки, начинающиеся с 0, как восьмеричные значения. parseInt('010') больше не должен выдавать 8 (хотя некоторые реализации решили сознательно нарушать это поведение ). И все же, полагаться на parseInt без второго «радикального» аргумента никогда не было хорошей практикой. Так что, если ваше приложение всегда задает radix, вам не о чем беспокоиться.

Так что обратитесь к Приложению E, протестируйте свой сценарий в более новых реализациях (желательно нескольких) и следуйте рекомендациям . Это хороший способ обеспечить совместимость.

...