Расширенная поддержка скриптов в IE9: поддержка ECMAScript 5 и выше

Автор: Topol Среда, Май 2nd, 2012 Нет комментариев

Рубрика: Операционные системы

До этого момента мы преимущественно говорили об улучшении быстродействия JavaScript в Internet Explorer  9, и не сказали почти ничего о новых или измененных функциях языка в движке «Chakra«. Теперь, с выпуском третьего Platform Preview, мы можем рассказать вам о новых возможностях JavaScript, которые вы можете испытать самостоятельно.

К слову, промышленным стандартом, определяющим язык JavaScript, является ECMA-262: ECMAScript Language Specification, разработанный и опубликованный Ecma International. В прошлом году исполнилось десять лет с момента представления третьей редакции ECMA-262 в декабре 1999 года. В декабре 2009 года Ecma одобрила пятую редакцию ECMA-262, являющуюся преемником третьей редакции (четвертая редакция никогда не публиковалась), и в прошлом же году мы представили частичную поддержку ECMAscript 5 (ES5), добавив поддержку JSON в IE8. Помимо JSON, однако, ES5 стандартизирует множество важных расширений в языке JavaScript.

Новые возможности ES5 в IE9 Platform Preview
В режим документов Standards в IE9 добавлено множество важных возможностей ES5:

Новые методы массива. Было добавлено девять новых методов для работы над массивами. Два из них, indexOf и lastIndexOf, поддерживают поиск определенного значения в массиве. По существу они схожи с одноименными функциями, что выполняют операции над строками. Остальные семь методов массивов позволяют управлять массивами при помощи стиля функционального программирования. Например, нижеприведенный фрагмент кода использует новый метод фильтра для сбора элементов массива, отвечающих определенному условию:

Код:
//функция, проверяющая, включен или отключен объект элемента меню
function enabled(menuItem) {return menuItem.status===»enabled»};

//Предположим, что отдельные элементы меню имеют свойство состояния (status property) и
//что объект меню имеет свойство элементов (items property), которое является массивом.
//Создаем новый массив, содержащий лишь включенные элементы меню
var enabledItems=myMenu.items.filter(enabled);

Эти методы поддерживают различные виды обработки массива без необходимости явного программирования циклов. Кроме этого, все методы являются универсальными, то есть они могут быть применены к любому объекту с пронумерованными свойствами, а не просто объектам, созданным при помощи конструктора массива. Вы можете испытать демо с использованием этих методов на веб-узле IE9 Test Drive. Также они обобщены в нижеприведенной таблице:

Метод массива
Описание
indexOf
Производит поиск первого появления определенного значения в массиве.
lastIndexOf
Производит поиск последнего появления определенного значения в массиве.
forEach
Применяет функцию к каждому элементу в массиве.
every
Устанавливает, является ли определенное состояние истинным для всех элементов в массиве.
some
Устанавливает, является ли определенное состояние истинным хотя бы для одного элемента в массиве.
map
Применяет функцию к каждому элементу в массиве и создает новый массив с соответствующими результатами
filter
Собирает в новый массив все элементы массива, для которых определенное состояние является истинным.
reduce
Собирает одно значение, основанное на всех элементах в массиве.
reduceRight
Собирает одно значение, основанное на всех элементах в массиве, обрабатывая их в обратном порядке.

Расширенная объектная модель. Важнейшей возможностью в этой областью являются свойства методов доступа. Их иногда также называют свойствами «getter/setter», поскольку они позволяют программистам, использующим JavaScript, контролировать, что происходит, когда программа получает или устанавливает значение свойства. Расширенная объектная модель ES5 также позволяет программистам контролировать, могут ли отдельные свойства менять свои значения, перечисленные выражениями for…in, а также могут ли свойства быть удалены или переопределены. Также она позволяет программисту контролировать, могут ли новые свойства быть добавлены в объект. ES5 также упрощает программистам, использующим JavaScript, создание объектов, наследуемых от определенного объекта-прототипа, а также просмотр определений свойств объекта и управление ими. Все эти возможности расширенной объектной модели доступны посредством новых свойств функции конструктора объекта. Тем не менее, следует заметить, что текущий выпуск IE9 Platform Preview не поддерживает целиком использование этих методов с DOM-объектами.

Функция объекта
Описание
Object.defineProperty
Создает или изменяет определение свойства. Свойство может быть определено либо как свойство данных, либо как свойство метода доступа, и для него могут быть установлены атрибуты записываемости (writable), перечисляемости (enumerable) и настраиваемости (configurable).
Object.defineProperties
Создает или изменяет несколько определений свойства посредством одной операции.
Object.create
Создает новый объект с определенным прототипом и, опционально, набором определенных свойств.
Object.getPrototypeOf
Получает прототип объекта от объекта аргумента.
Object.getOwnPropertyDescriptor
Возвращает полное описание атрибутов свойства объекта.
Object.getOwnPropertyDescriptor
Возвращает массив, содержащий имена всех ненаследуемых свойств объекта.
Object.keys
Возвращает массив, содержащий имена всех ненаследуемых свойств объекта, которые будут повторены выражением for…in.
Object.seal
Запрещает добавление любых дополнительных свойств к объекту аргумента и запрещает удаление или переопределение любых существующих свойств. Отдельные значения свойств по-прежнему могут быть изменены, если для них установлен атрибут записываемости writable.
Object.freeze
Запрещает добавление любых дополнительных свойств к объекту аргумента и запрещает удаление и переопределение любых существующих свойств. Кроме этого, значения существующих свойств не могут быть изменены.
Object.isSealed
Проверяет, был ли объект запечатан при помощи Object.seal.
Object.isFrozen
Проверяет, был ли объект зафиксирован при помощи Object.freeze.
Object.preventExtensions
Запрещает добавление любых дополнительных свойств к объекту.
Object.isExtensible
Проверяет, могут ли новые свойства быть добавлены к объекту.

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

Метод или функция
Описание
String trim
Удаляет пробелы из начала и конца строки.
Date toISOString
Преобразовывает Date в формат строки, который должны поддерживать все реализации ES5.
Date.parse
Существующая функция расширена для распознавания формата, созданного с помощью toISOString.
Date.now
Возвращает числовой штамп времени.
Array.isArray
Надежно проверяет, является ли объект массивом.
Function bind
Задает фиксированные значения некоторым из аргументов функции.

ES5 также содержит ряд других незначительных изменений и технических исправлений в языке. Многие из них не повлияют на большинство программистов, поскольку они просто стандартизируют возможности, всегда поддерживавшиеся в браузерах. Примером таких функций является объединение строк в строчных литералах. Другое небольшое изменение представляет больше интереса. Такие зарезервированные имена как ifsuper и public могут теперь использоваться в качестве имен свойств объектных литералов и для доступа к свойству, следующему за точкой. Благодаря этому изменению программистам более не придется беспокоиться о длинных и произвольных списках слов, которые они не могли легко использовать в качестве имен свойств.

«Одинаковый скрипт, одинаковая разметка»
Обновление JavaScript в IE9 не ограничивается поддержкой новых возможностей ES5. Сюда также относится стремление убедиться, что разработчики смогут использовать в IE9 ту же разметку и те же скрипты, что они используют в других браузерах. Ранее в этом году мыопубликовали документы, подробно описывающие отличия реализации JavaScript в IE8 от третьей редакции спецификаций ECMAScript. При разработке режима IE9 Standards мы обратили особое внимание на эти различия и внесли изменения, позволяющие IE9 исполнять те же скрипты, что и другие браузеры.

Исправленная проблема
Пример
Выражения функций обрабатывались, как если бы они были объявлениями функций
Код:
function f() {alert(«declaration»)};
obj.callback=function f() {alert(«expression»)};
f(); // IE8 неверно оповещает «expression»
Имена функций в выражениях функций не были локально определены в теле функции
Код:
var fact=»the web is big»;
Math.factorial=function fact(n)
{return n<=1?1:fact(n-1)};
alert(Math.factorial(9)); // IE8 вызывает исключение
Параметры конструкции слежения были видны во внешней области
Код:
var e = «outer»;
try {throw «inner»} catch(e) {};
alert(e); // IE8 неверно оповещает «inner»
Во многих случаях вызванное исключение времени выполнения было отлично от указанного в стандарте
Код:
var obj; //значение obj не определено
try {alert(obj.prop)}
catch (e) {
if (e instanceof ReferenceError) alert(«correct»)
else if (e instanceof TypeError) alert(«IE8 wrong»)
}
Закрывающие запятые в литералах массива добавлялись в длину массива
Код:
var len = [1,2,3,].length;
alert(len); //должно быть 3, IE8 сообщает 4
Пустые элементы в литералах массива не приводили к разреженному массиву
Код:
var a=[0,,2,,4];
alert(a.hasOwnProperty(1));// IE8 неверно сообщает истину
Атрибут dontenum наследовался собственными свойствами
Код:
var obj={valueOf:0, toString:1,foo:2};
var n=0;
for (var p in obj) n++;
alert(n); // IE8 отображает 1, а должен 3
\v не распознавался как escape-последовательность из-за непечатаемых символов вертикальной табуляции
Код:
alert(«\v»===»v»);//IE8 сообщает истину, а должен ложь
alert(«\v»===»\u000b»);
//IE8 возвращал ложь, а должен истину
Глобальный объект не наследовал из Object.prototype
Код:
alert(hasOwnProperty===undefined);
// IE8 неверно сообщает истину, а должен ложь
Неудовлетворенные круглые скобки в регулярных выражениях приводили к пустой строке вместо неопределенного значения
Код:
var x=/((a)|(ab))((c)|(bc))/.exec(«abc»);
// x должен быть:
//    ["abc","a","a",undefined, "bc",undefined, "bc"]
// IE8 производит: ["abc","a","a","","bc","","bc"]
toFixed некорректно округлял некоторые диапазоны значений
Код:
alert((0.09).toFixed(1));
// должно отображаться 0.1
// IE8 отображает 0.0

«Использование одинаковых скриптов» касается не только того, как скрипты могут исполняться в Internet Explorer. Сюда также относится стремление убедиться, что скрипты, которые вы разрабатываете и тестируете в IE, также будут работать в любых других соответствующих стандартам браузерах, которые могут использовать ваши пользователи. Одна из проблем, которая может препятствовать достижению этой цели, заключается в возможностях, поддерживающихся исключительно в IE и отсутствующих в других браузерах. Если такая функция не является принципиально важной для функциональности браузера и не имеет уникального значения, реализована в одном единственном браузере и, по-видимому, не станет частью веб-стандарта, то она превращается в опасность для совместимости. Если вы непредусмотрительно используете такую функцию в вашем скрипте, то ваши пользователи не смогут работать с ним в каких-либо других браузерах.

В реализации JavaScript в Internet Explorer исторически имеется несколько функций, подпадающих под эту категорию, которые мы решили исключить из IE9 Standards Mode. В основном это функции, добавленные в качестве расширений возможностей на ранних стадиях разработки IE. Однако они не были добавлены в другие браузеры, и сегодня становится очевидным, что они никогда не будут включены в стандарт ECMAScript.

Первой функцией в этой категории является возможность добавления точки с запятой после любого блока кода. Например, IE разрешал заявления типа «if», составленные следующим образом:

Код:
if (conditionMet) {performTrueAlternative()};
else {performFalseAlternative()};

Обратите внимание на точку с запятой в конце первой строки. Стандарт ECMAScript никогда не допускал постановки точки с запятой на такой позиции. Если вы попытаетесь загрузить скрипт, содержащий этот код, в любом браузере, отличном от IE, то в нем будет обнаружена ошибка синтаксиса, и скрипт не будет загружен. Первоначально эта функция была добавлена из-за желания быть предельно нестрогими в отношении того, что может исполнять IE — в том числе пропускать некоторые ошибки синтаксиса. К сожалению, желание быть нестрогими приводит к проблемам совместимости при запуске скрипта в других браузерах. В таких случаях лучше, что бы было выведено сообщение об ошибке, и она была исправлена разработчиком скрипта.

В IE также имеется ряд расширений к синтаксису объявления функции. Одно из расширений позволяет объявлениям функции напрямую определять свойства метода объекта. Например:

Код:
function String.prototype.firstChar() {return this.substring(0,1)};

означает то же самое, что

Код:
String.prototype.firstChar = function (){return this.substring(0,1)};

Другое расширение позволяло объявлению функции определять несколько имен функции. Например код:

Код:
function declaration,dcl() {return processDeclaration)()};

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

Заметьте, что это не означает, что мы удалили все функции, присущие исключительно реализации JavaScript в IE. Некоторые функции жизненно необходимы в случаях, когда разработчику требуется получить доступ к уникальным возможностям Internet Explorer или Microsoft Windows. Например, сюда относятся возможности JavaScript, поддерживающие доступ к объектам ActiveX.

Тестирование прогресса
Первостепенной целью при разработке IE9 является обеспечение единой разметки, которую можно было бы использовать во всех браузерах, к чему, конечно, относится и JavaScript. Так как же мы узнаем о нашем продвижении к этой цели? В одной из предыдущих статей мы говорили об отношении Microsoft к разрабатываемому набору тестов JavaScript. Мы считаем, что организации, ответственные за веб-стандарты, должны опубликовать окончательный набор тестов, гарантирующий работу одинаковых скриптов и одинаковой разметки во всех браузерах. На данный момент стандартизированного набора тестов для JavaScript не существует. Комитет стандартов ECMAScript согласился разработать такой набор, и мы ведем над ним совместную работу с разработчиками других браузеров, являющихся членами Ecma. Этот набор тестов еще не завершен и не опубликован. Тем временем, более 1300 относящихся к ES5 тестов, которые мы используем и планируем предложить Ecma, доступно на веб-узле Internet Explorer Testing Center. В результате добавленной нами поддержки ES5, IE9 теперь проходит все шестнадцать тестов Acid3 в группе 6 (JavaScript).

Испытайте самостоятельно
Нам нужны ваши отзывы. Дайте нам знать при обнаружении ошибки в JavaScript. В особенности нас интересуют проблемы совместимости. Если вы используете стандартизированную возможность JavaScript, и в режиме Standards в IE9 Platform Preview она работает иначе, чем в других браузерах, возможно, вы обнаружили ошибку — сообщите о ней на Connect. Поскольку вышеописанные изменения относятся лишь к режиму IE9 Standards, веб-узлы, работающие в режимах совместимости, не отражают этих изменений и продолжают вести себя по-прежнему.

Наконец, внимательно просмотрите ваш код на использование определения браузера для известных различий или ошибок JavaScript в IE, поскольку, скорее всего, оно более не будет работать в режиме IE9 Standards. Это уже не тот же самый старый JavaScript в IE.

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты