<b> Object.prototype.toString.call(o) === "[object Array]";</b>
<b>};</b>
Фактически именно такая проверка атрибута
<b>class</b>
выполняется в функции
<b>Array.isArray()</b>
, определяемой стандартом ECMAScript 5. Прием определения класса объекта с помощью
<b>Object.prototype.toString()</b>
был описан в разделе 6.8.2 и продемонстрирован в примере 6.4.
7.11. Объекты, подобные массивам
Как мы уже видели, массивы в языке JavaScript обладают некоторыми особенностями, отсутствующими в других объектах:
• Добавление нового элемента вызывает автоматическое обновление свойства
<b>length</b>
.
• Уменьшение значения свойства
<b>length</b>
вызывает усечение массива.
• Массивы наследуют множество удобных методов от
<b>Array.prototype</b>
.
• Атрибут
<b>class</b>
массивов имеет значение «Array».
Все эти характеристики отличают массивы в языке JavaScript от других объектов. Но они не главное, что определяет массив. Часто бывает удобно организовать работу с произвольным объектом, как со своего рода массивом - через свойство
<b>length</b>
и соответствующие неотрицательные целочисленные свойства.
Такие объекты, «подобные массивам», иногда используются для решения практических задач, и хотя с ними нельзя работать через методы массивов или ожидать специфического поведения свойства
<b>length</b>
, все же можно организовать перебор свойств объекта теми же программными конструкциями, которые используются при работе с настоящими массивами. Оказывается, что значительное число алгоритмов для работы с массивами вполне пригодно для работы с объектами, подобными массивам. Это особенно верно, если используемые алгоритмы не изменяют массивы или хотя бы не затрагивают его свойство
<b>length</b>
.
В следующем фрагменте создается обычный объект и к нему добавляются дополнительные свойства, которые превращают его в объект, подобный массиву, после чего производится перебор «элементов» получившегося псевдомассива:
<b>var а = {}; // Для начала создать обычный пустой объект</b>
<b>// Добавить свойства, которые сделают его похожим на массив </b>
<b>var і = 0;</b>
<b>while(i < 10) {</b>
<b> a[i] = і * і;</b>
<b> і++;</b>
<b>}</b>
<b>a.length = і;</b>
<b>// Теперь можно обойти свойства объекта, как если бы он был настоящим массивом</b>
<b>var total = 0;</b>
<b>for(var j = 0; j < a.length; j++) total += a[j];</b>
Объект
<b>Arguments</b>
, который описывается в разделе 8.3.2, является объектом, подобным массиву. В клиентском языке JavaScript такие объекты возвращаются многими методами объектной модели документа (DOM), такими как метод
<b>document</b>
.
<b>getElementsByTagName().</b>
Следующая функция проверяет, является ли объект подобным массиву:
<b>// Определяет, является ли о объектом, подобным массиву. Строки и функции имеют </b>
<b>// числовое свойство length, но они исключаются проверкой typeof.</b>
<b>// В клиентском JavaScript текстовые узлы D0M имеют числовое свойство length </b>
<b>// и, возможно, должны быть исключены дополнительной проверкой </b>
<b>o.nodeType != 3.</b>
<b>function isArrayLike(o) {</b>
<b> if (о && // о не null, не undefined и т. д.</b>
<b> typeof о === "object" && //о - объект</b>
<b> isFinite(o.length) && // о.length - конечное число</b>
<b> о.length >= 0 && // о.length - положительное</b>
<b> о.length===Math.floor(o.length) && // о.length - целое </b>
<b> о.length < 4294967296) </b>
<b> // о.length < 2~32</b>
<b> return true; // Значит, объект о подобен массиву</b>
<b> else</b>
<b> return false; // Иначе - нет</b>
<b>}</b>
В разделе 7.12 будет показано, что строки в ECMAScript 5 ведут себя подобно массивам (и некоторые броузеры обеспечивали возможность обращения к символам в строке по индексам еще до выхода ECMAScript 5). Однако проверки на подобие массивам, такие как приведенная выше, для строк обычно возвращают
<b>false</b>
-с ними лучше работать как со строками, чем как с массивами.
Методы массивов в языке JavaScript преднамеренно были сделаны достаточно универсальными, чтобы их можно было использовать не только с настоящими массивами, но и с объектами, подобными массивам. В ECMAScript 5 все методы массивов являются универсальными. В ECMAScript 3 универсальными также являются все методы, за исключением
<b>toString()</b>
и
<b>toLocaleString()</b>
. (К исключениям также относится метод
<b>concat()</b>
: несмотря на то что его можно применять к объектам, подобным массивам, он некорректно разворачивает объекты в возвращаемый массив.) Поскольку объекты, подобные массивам, не наследуют свойства от
<b>Array.prototype</b>
, к ним нельзя напрямую применить методы массивов. Однако их можно вызывать косвенно, с помощью метода
<b>Function.call():</b>
<b>var а = {"О":"а", ”2":"с”, length:3}; // Объект, подобный массиву</b>