Как я могу доказать, что мои файлы JavaScript находятся в области конкретной версии JS или ECMA?

Скажем, вы получите кучу файлов .js, и теперь ваша работа должна сортировать их по следующим группам:

  • требуется, по крайней мере, JavaScript 1.85
  • требуется, по крайней мере, E4X (ECMAScript 4 EX)
  • требуется, по крайней мере, ECMAScript 5

или что-то вроде этого.

Меня интересует любое решение, но особенно в тех, которые работают с использованием JavaScript или PHP. Это используется для создания автоматизированных спецификаций, но это не имеет значения - это хорошая задача, которую нужно легко решить, однако я понятия не имею, как и для меня это нелегко. Итак, если вам это легко, поделитесь любыми подсказками.

Я бы ожидал чего-то подобного: http://kangax.github.com/es5-compat-table/# - просто не для браузеров, а для того, чтобы данный файл был проверен на разные реализации JavaScript.

Я предполагаю, что каждая версия должна иметь некоторые особенности, на которые можно протестировать. Тем не менее, все, что я могу найти, это материал о "какой версии поддерживает этот браузер".


PS: Не принимайте "сейчас это ваша работа" в буквальном смысле, я использовал его, чтобы продемонстрировать задачу, а не подразумевать, что я ожидаю, что работа будет выполнена для меня; в то время как в процессе решения этого было бы неплохо иметь какую-то помощь или направление.


EDIT: я выбрал простой выход, вернув ECMAScript 5, чтобы он поддерживался, по крайней мере, так же хорошо, как и текущий FireFox для моего проекта, чтобы работать как ожидаемый и ожидаемый.

Однако меня все еще интересует любое решение - attemps или хотя бы определенный ответ "возможен (с XY)" или "невозможно, потому что..."; XY может быть только некоторым ключевым словом, например FrameworkXY или DesignPatternXY, или любым другим, или более подробным решением, конечно.

Ответы

Ответ 1

Это невозможно в точности, и это также отличный способ взглянуть на вещи для этого типа проблем.

Почему его невозможно

Javascript не имеет статической типизации. Но свойства определяются цепью прототипа. Это означает, что для любой части кода вы должны были бы указать тип объекта и проверить цепочку прототипов, прежде чем определять, какую функцию вызывается для вызова функции.

Вы, например, должны были бы сказать, что $(x).bind() o $(x).map не выполняет вызовы функций ecmascript5 map или bind, а jQuery. Это означает, что вам действительно нужно разобрать весь код и сделать вывод о типе. Если бы у вас не было всей базы кода, это было бы невозможно. Если бы у вас была функция, которая взяла объект, и вы вызвали bind, вы бы понятия не имели, если это должно быть Function.prototype.bind или jQuery.bind, потому что это не определено до выполнения. Фактически, его возможная (хотя и не хорошая практика кодирования), что она может быть и то, и другое, зависит от ввода функции или даже зависит от ввода пользователя. Таким образом, вы можете угадать об этом, но вы не смогли бы этого сделать точно.

Сделать все это еще более невозможным, функция eval в сочетании с возможностью получения пользовательских данных или данных ajax означает, что вы даже не знаете, какие типы некоторые объекты являются или могут быть, даже если оставить в стороне проблему, которая может попытайтесь запустить код, соответствующий любой спецификации.

Вот пример фрагмента кода, который вы не могли разобрать

var userInput = $("#input").val();

var objectThatCouldBeAnything = eval(userInput);

object.map(function(x){
   return !!x; 
});

Невозможно определить, обрабатывает ли этот код объект jQuery в eval и работает jQuery.map или создает массив и работает Array.prototype.map. И это сила и слабость динамически типизированного языка, такого как javascript. Это обеспечивает огромную гибкость, но ограничивает то, что вы можете сказать о коде перед временем выполнения.

Почему это не хорошая стратегия

Спецификации ECMAScript являются стандартными, но на практике они никогда не выполняются идеально или последовательно. Различные среды реализуют разные части стандарта. Наличие кода "ECMAScript5" не гарантирует, что какой-либо конкретный браузер полностью реализует все свои свойства. Вам действительно нужно определить это на основе свойства по свойствам.

Что вам гораздо лучше делать, это найти список функций или свойств, которые используются кодом. Затем вы можете сравнить это с поддерживаемыми свойствами для конкретной среды.

Это по-прежнему трудно поддается решению по указанным выше причинам, но, по крайней мере, полезно. И вы могли бы воспользоваться этим, даже используя свободное приближение (предполагая, что bind фактически является ecmascript5, если только на обертке $(). Это не будет идеальным, но все равно может быть полезным).

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

Ответ 2

По сути, вы ищете минимальные требования к некоторому файлу javascript. Я бы сказал, что это невозможно до запуска. JavaScript - это динамический язык. Таким образом, у вас нет ошибок времени компиляции. В результате вы не можете сказать, пока не находитесь в каком-то закрытии, что-то не работает, и даже тогда это будет вводить в заблуждение. На ваших зависимостях можно исправить многие проблемы совместимости.

Пример:

  • JS File A использует некоторую функцию ES5
  • JS File B обеспечивает прокладку для браузеров с недостаточной степенью защиты ES5 или, по крайней мере, имитирует их каким-то образом.
  • JS File A и B всегда загружаются вместе, но независимо A выглядит так, как будто это не сработает.

Пример 2:

  • Object.create - это то, что вы хотите протестировать.
  • Какой-то парень по имени Crockford добавляет создание в Object.prototype
  • Object.create теперь работает в менее совместимых браузерах, и ничего не сломается.

Решение 1:

  • Создайте или найдите карту зависимостей. У вас определенно уже есть карта зависимостей, либо явно, либо вы можете сгенерировать ее путем итерации над вашими HTML файлами.
  • Запустите все соответствующие коды кода в средах с уменьшающейся функциональностью (например: ES5, затем E4X, затем JS 1.x и т.д.).
  • Как только пакет JS файлов выходит из строя для некоторого кода, вы знаете их минимальное требование.
  • Возможно, вы можете перебирать публичные функции в своих объектах и ​​использовать инъекцию зависимостей для заполнения конструкторов и методов. Это звучит очень тяжело, хотя.

Решение 2:

  • Используйте webdriver, чтобы посещать страницы в различных средах.
  • Карта window.onerror к функции, которая сообщает вам, что ваша текущая страница сломалась при выполнении некоторых действий.
  • При ошибке вы узнаете, что есть проблема с пакетом на текущей странице, чтобы сохранить эти данные.

Оба эти решения предполагают, что вы всегда пишете идеальный JS, который никогда не имеет ошибок, к чему вы должны стремиться, но не реалистичны. Это может; однако, дайте вам некоторые базовые "дымовые испытания".