Следующая функция отыскивает заданное значение в массиве и возвращает массив всех индексов, где было найдено совпадение. Здесь демонстрируется, как можно использовать второй аргумент метода indexOf()
для поиска совпадений после первого.
// Отыскивает все вхождения значения х в массив и возвращает
// массив индексов найденных совпадений
function findall(a. х) {
var results = [], // Возвращаемый массив индексов
len = a.length, // Длина массива, где выполняется поиск
pos = 0; // Начальная позиция поиска
while(pos < len) { // Пока остались непроверенные элементы...
pos = a.indexOf(x, pos); // Искать
if (pos === -1) break; // Если ничего не найдено, поиск завершен.
results.push(pos); // Иначе - сохранить индекс в массиве
pos = pos +1; //И продолжить поиск со следующего элемента
}
return results; // Вернуть массив индексов
}
Обратите внимание, что строки также имеют методы indexOf()
и lastlndexOf(),
которые действуют подобно методам массивов.
На протяжении этой главы мы не раз имели возможность убедиться, что массивы являются объектами, обладающими особыми чертами поведения. Получая неизвестный объект, иногда бывает полезно проверить, является он массивом или нет. Сделать это в реализации ECMAScript 5 можно с помощью функции Array. isArray():
Array.isArray([]) // => true
Array.isArray({}) // => false
Однако до выхода стандарта ECMAScript 5 отличить массивы от других объектов было удивительно сложно. Оператор typeof
никак не помогает в этом: для массивов он возвращает строку "object" (и для всех других объектов, кроме функций). В простых случаях можно использовать оператор instanceof
:
[] instanceof Array // => true
({}) instanceof Array // => false
Проблема применения оператора instanceof
состоит в том, что в веб-броузерах может быть открыто несколько окон или фреймов. Каждое окно или фрейм имеет собственное окружение JavaScript, с собственным глобальным объектом. А каждый глобальный объект имеет собственное множество функций-конструкторов. Поэтому объект из одного фрейма никогда не будет определяться как экземпляр конструктора в другом фрейме. Даже при том, что путаница между фреймами возникает довольно редко, тем не менее этого вполне достаточно, чтобы считать оператор instanceof
ненадежным средством определения принадлежности к массивам.
Решение заключается в том, чтобы выполнить проверку атрибута class
(раздел 6.8.2) объекта. Для массивов этот атрибут всегда будет иметь значение «Array», благодаря чему в реализации ECMAScript 3 функцию isArray()
можно определить так:
var isArray = Function.isArray || function(o) {
return typeof о === "object" &&
Object.prototype.toString.call(o) === "[object Array]";
};
Фактически именно такая проверка атрибута class
выполняется в функции Array.isArray()
, определяемой стандартом ECMAScript 5. Прием определения класса объекта с помощью Object.prototype.toString()
был описан в разделе 6.8.2 и продемонстрирован в примере 6.4.
7.11. Объекты, подобные массивам
Как мы уже видели, массивы в языке JavaScript обладают некоторыми особенностями, отсутствующими в других объектах:
• Добавление нового элемента вызывает автоматическое обновление свойства length
.
• Уменьшение значения свойства length
вызывает усечение массива.
• Массивы наследуют множество удобных методов от Array.prototype
.
• Атрибут class
массивов имеет значение «Array».
Все эти характеристики отличают массивы в языке JavaScript от других объектов. Но они не главное, что определяет массив. Часто бывает удобно организовать работу с произвольным объектом, как со своего рода массивом - через свойство length
и соответствующие неотрицательные целочисленные свойства.
Такие объекты, «подобные массивам», иногда используются для решения практических задач, и хотя с ними нельзя работать через методы массивов или ожидать специфического поведения свойства length
, все же можно организовать перебор свойств объекта теми же программными конструкциями, которые используются при работе с настоящими массивами. Оказывается, что значительное число алгоритмов для работы с массивами вполне пригодно для работы с объектами, подобными массивам. Это особенно верно, если используемые алгоритмы не изменяют массивы или хотя бы не затрагивают его свойство length
.
Читать дальше
Конец ознакомительного отрывка
Купить книгу