Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Когда мы впервые представили планы по Internet Explorer Platform Previews, то отмечали что «разработчики и те, кто интересуется стандартами и веб-разработкой, могут оценить функциональность новой платформы и заблаговременно оставить отзыв». Сейчас мы ежедневно получаем многочисленные отзывы и используем их для улучшения IE9. Однако иногда влияние отзывов выходит за пределы только IE9. Вот история о том, как недавний отзыв привел к корректировке нового стандарта JavaScript – ECMAScript 5th Edition (ES5).
Стандарт ES5 был официально представлен в декабре 2009 года, и третья предварительная версия IE9 стала первой широко распространенной версией, в которой были реализованы некоторые тонкие детали спецификации ES5. Стандарт ES5 разрабатывался с условием совместимости с существующими веб-сайтами, и международный технический комитет европейской ассоциации производителей ЭВМ TC39 старался избежать любых изменений, которые могут повлиять на безопасность и нарушить существующий код JavaScript. Однако в мире программного обеспечения не существует ничего совершенного, поэтому с третьим выпуском IE9 Platform Preview нам было интересно узнать о любых проблемах совместимости ES5 с существующими сайтами.
Вскоре после выхода третьей предварительной версии мы получили сообщение о том, что в ней некорректно работают некоторые веб-приложения, использующие библиотеку jQuery. Мы проследили эту проблему вплоть до конкретного метода API библиотеки, который в некоторых случаях допускает вызовы метода Object.prototype.toString без предварительной проверки аргумента на значение null или undefined. Конкретно, некоторые вызовы этого метода jQuery:
isFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
},
выдают ошибку: «TypeError: Object expected». Последующий анализ показал, что toString в этом коде является встроенным методом Object.prototype.toString и что сбой происходит, когда isFunction вызывается со значением аргумента undefined. Почему ошибка случается в IE9, но не в предыдущих версиях или других браузерах? Потому что третья предварительная версия платформы IE9 фактически подчиняется спецификации ES5 Object.prototype.toString.
В соответствии с прежними версиями спецификации ECMAScript, вызов любого встроенного метода, использующего в качестве this значение null или undefined, передает методу «глобальный объект» (в браузерах это объект DOM window) как его значение this. Это открывает ряд потенциальных брешей в безопасности инфраструктур, нацеленных на безопасную поддержку гибридных веб-приложений.
Спецификация ES5 изменила ситуацию так, что значения null или undefined не заменяются объектом window, и определение каждого встроенного метода было обновлено, главным образом, в части получения этих значений, как их параметров this. Технический комитет ECMAScript попробовал сделать это при условии совместимости для нормального использования и генерации исключений в случаях, когда это невозможно. undefined был определен в ES5 для генерации таких исключений. Это и создает проблему совместимости, описанную выше.
Проблема может быть легко решена изменением кода jQuery (выделено красным цветом):
isFunction: function( obj ) {
return obj && toString.call(obj) === "[object Function]";
}
Команда jQuery действительно собирается внести это изменение. Однако такое изменение не исправит тысячи локальных копий jQuery которые уже существуют в интернете. Учитывая широкое распространение jQuery, становится ясно, что ES5 содержит серьёзную проблему совместимости. Понятно как мы можем изменить исполнение реализацию ES5 в IE9, чтобы решить проблему. Можно вернуть такое же строковое значение ("[object Object]"), которое возвращает IE8 в этой ситуации. Это решение не создаст каких-либо проблем в безопасности, которые ES5 старается исключить. Однако мы не хотим в одностороннем порядке вносить это изменение в нашу реализацию нового стандарта. Это не решит проблем совместимости и интероперабельности: если в IE проблема будет решена одним способом, то в других браузерах – другим или вообще не решена.
Как только мы поняли проблему и пути её решения, я описал её в дискуссионной группе TC39 es5-discuss как ошибку обратной совместимости. Моё первое сообщение по поводу данной проблемы было размещено в 17:51 25 июня в пятницу. К 22:00 был получены ответы от членов TC39, представлявших Apple, Mozilla и Google. Все согласились, что данная проблема относится к совместимости и должна быть исправлена, и что генерация исключения в данном случае не обязательна и не желательна. Мы также первоначально согласились с тем, что идея о возврате такого же строкового значения, что и в ES3 в данном случае выглядит как хорошая идея. Однако из дальнейших сообщений после выходных мы поняли, что не все браузеры могут вернуть в данной ситуации "[object Object]", а также некоторые другие экспериментальные значения, включая "[object Window]" и "[object Global]". Предлагалось возвращать "[object null]" и "[object undefined]". Показалось, что это лучшее решение, поскольку оно не только снимает проблему с jQuery, но также четко различает null и undefined от фактических объектов. Также это лучше для интероперабельности браузеров, так как она требует, чтобы браузеры выдавали идентичные результаты, а не так, как в ситуации с ES3, когда различные браузеры выдают различные результаты.
Ко вторнику в дискуссионной группе был достигнут консенсус и последовало окончательное предложение. Как только мы пришли к согласию, я отдал измененную спецификацию undefined нашей группе разработчиков IE9 JavaScript, чтобы они смогли создать исправление вовремя и широкого протестировать его со следующим предварительным выпуском IE9. Разработчики Mozilla также сообщили, что они внедрят это исправление в следующую бета-версию Firefox. Я также внес изменения в официальный список ошибок для ES5, так что это изменение спецификации зафиксировано там (параграф 15.2.4.2).
Веб-стандарты являются комплексным продуктом, имеющим отношение к ПО, и, как все программы, они содержат ошибки. Иногда лучшим способом найти и исправить ошибки совместимости является реализация и развёртывание этого стандарта среди широко используемых браузеров. Обычно такое бывает в ранних выпусках, как в случае с предварительными версиями IE9. Так что когда вы, как разработчик веб-страниц, составляете отзывы на такие выпуски, вы не только предоставляете отзыв на определенный браузер, но также на новые и внедряющиеся стандарты, которые он реализует. Конечно, чтобы такой отзыв дал результат, разработчикам браузеров и авторам стандартов необходимо иметь возможность и готовность быстро отреагировать на отзывы, которые рапортуют о существенных проблемах. Быстрая ответная реакция на проблемы с ES5 jQuery toString и другие проблемы с ES5 показывает, как разработчики браузеров и другие члены TC39 могут работать совместно для обеспечения большей совместимости и интероперабельности в интернете. Но все это становится возможным благодаря вашим отзывам. Так что, пожалуйста, держите нас в курсе.
Аллен Вирфс-Врок (Allen Wirfs-Brock)
Архитектор языка JavaScript Microsoft
Comments
- Anonymous
December 25, 2011
JavaScript error: Object expected Как исправить эту ошибку. Невозможно работать с IE!!!!!!!!!!!!!!