Массивы в JavaScript представляют собой объектный тип данных, служащий для хранения и обработки множества значений (чаще всего одного типа данных). Использование массивов в некоторых сценариях позволяет сделать код более компактным, в первую очередь благодаря сокращению количества объявляемых переменных. Массивы создаются при помощи оператора new. Существует три варианта вызова конструктора Array():
/* обычный синтаксис */ var array = [ elem0, elem1, elem2, ... ] var empty = [] /* Синтаксис с new Array() */ var empty = new Array(); // создание пустого массива var a = new Array(length); // создание массива из "length" неопределенных значений var a = new Array(item1, item2, ...); // создание массива из заданных значений
Элементы массива хранятся последовательно, причем, каждый элемент имеет свой индекс (номер по порядку). Нумерация элементов массивов в JavaScript начинается с нуля. Для доступа к элементу массива используют имя массива и индекс элемента, записанный после имени в квадратных скобках:
a[0] = 2; b = a[0]*2;
Для ввода массива с клавиатуры чаще всего используют цикл. Если количество элементов массива известно заранее, используют цикл for. В противном случае подойдет цикл с постусловием do…while. Приведем пример:
var a = new Array(); var count = 10; for (var i=0; i<count; i++) a[i]=parseInt(prompt("Введите целое число:", "")); alert("Массив: "+a.join(", ")); // вывод массива
В приведенном фрагменте кода массив выводится в виде строки, где элементы массива разделяются символами ", ". Если массив необходимо вывести поэлементно, то можно будет снова использовать цикл for, так как длина массива нам известна и возвращается свойством length объекта Array().
Для добавления элементов в массив можно воспользоваться методами push() и unshift(). Метод push() добавляет элементы в конец массива, а метод unshift() - в начало. Рассмотрим пример применения этих методов:
var a = new Array(1,2,3); alert ("Исходный массив: "+a.join(", ")); if (confirm("Добавить в начало?")) { a.unshift(-2,-1,0); } else { a.push(4,5,6); } alert ("Итоговый массив: "+a.join(", "));
Эти методы не позволяют добавить массив в массив. Для этих целей используйте метод concat()
Для удаления элементов из массива используйте методы pop() и shift(). Метод pop() удаляет последний элемент массива, а метод shift() - первый. Рассмотрим пример применения этих методов:
var a = new Array(0,1,2,3, 4); alert ("Исходный массив: "+a.join(", ")); if (confirm("Удалить первый?")) { a.shift(); } else { a.push(); } alert ("Итоговый массив: "+a.join(", "));
Для удаления элемента располагающегося не в начале или в конце массива можно использовать метод splice() со следующими параметрами: splice(index, 1), где index - номер удаляемого элемента. Следующий пример демонстрирует удаление элемента с индексом "2":
var a = new Array(1,2,3,4); alert ("Исходный массив: "+a.join(", ")); a.splice (2,1); alert ("Итоговый массив: "+a.join(", "));
Метод sort(), как упоминалось выше, позволяет выполнить сортировку, т.е. упорядочивание, элементов массива по заданному критерию. По умолчанию метод sort() рассматривает элементы как строки и критерием считается порядок символов строки в соответствии с таблицей ASCII. Для реализации других критериев сортировки элементов вы должны будете написать функцию, которая определяет порядок сортировки и строится следующим образом:
функция должна принимать два параметра (назовем их a1 и a2) в случае, если a1 > a2, функция должна вернуть положительное значение в случае, если a1 < a2, функция должна вернуть отрицательное значение в случае, если a1 == a2, функция должна вернуть 0. Рассмотрим вышесказанное на практике: необходимо ввести массив целых чисел и отсортировать его по возрастанию и убыванию значений элементов.
Листинг: сортировка элементов массива методом 'sort()'
// объявление и ввод массива var a = new Array(); var count = 5; for (var i=0; i<count; i++) a[i]=parseInt(prompt("Введите целое число:", "")); alert("Неотсортированный массив: "+a.join(", ")); // вывод массива a.sort(); alert("Строковая сортировка массива: "+a.join(", ")); // вывод массива a.sort(numUp); alert("Числовая сортировка по возрастанию: "+a.join(", ")); // вывод массива a.sort(numDown); alert("Числовая сортировка по убыванию: "+a.join(", ")); // вывод массива // функции сравнения элементов function numUp(a1, a2) { // сортировка по возрастанию return a1-a2; } function numDown(a1, a2) { // сортировка по убыванию return a2-a1; }
Свойство prototype позволяет добавить в готовый объект новое свойство или метод. Для того, чтобы лучше понять принципы работы с этим замечательным свойством рассмотрим пример реализации метода max() (поиск максимального элемента) в массиве:
Листинг: использование сойства 'prototype'
function array_max(){ var i, max = this[0]; for (i = 1; i < this.length; i++) if (max < this[i]) max = this[i]; return max; } Array.prototype.max = array_max; var a = new Array(); var count = 5; for (var i=0; i<count; i++) a[i]=parseInt(prompt("Введите целое число:", "")); alert("Массив: "+a.join(", ")); // вывод массива alert("Максимум: "+a.max()); // вывод максимума
В примере сначала описывается функция array_max(), определяющая максимум текущего массива, обращаясь к его свойствам и элементам посредством указателя this. Затем, строка Array.prototype.max = array_max; добавляет метод max() в массив. Вызов метода max() осуществляется традиционным образом.
К сожалению, в JavaScript отсутствует стандартная реализация многомерных массивов (даже 2-мерных). Однако, этот печальный недостаток можно обойти, создав массив массивов. Для этого необходимо создать массив, а, затем, каждый элемент этого массива так же сделать массивом. Выглядит это примерно так:
var n=3, //количество строк m=5; //количество элементов в строке (столбцов) var a = new Array (); for (var i=0; i<n; i++) { a[i] = new Array (); //каждый элемент массива тоже массив! for (var j=0; j<m; j++) { a[i][j] = i*j; } }
В приведенном примере создается и заполняется двумерный массив. Таким же образом можно создать и массивы большей размерности (3,4,5 и т.д). Для перебора элементов многомерных массивов используются вложенные циклы. Количество вложенных циклов, как правило, определяется количеством измерений создаваемого массива. На практике редко применяются даже двумерные массивы, не говоря уже о массивах большей размерности.
До сих пор говорилось, о том, что индекс элемента в массиве - целое число, определяющее порядковый номер элемента. На самом деле, индексом элемента в массиве может быть и уникальный в рамках одного массива строковый идентификатор (то есть строка!). Возникает вполне резонный вопрос - зачем это нужно? Если вдуматься, то использование строк в качестве идентификаторов элемента массива в ряде случаев оказывается полезным. Можно, например, хранить в массиве пароли пользователей, а индексами элементов считать имена пользователей:
var users = new Array(); users["admin"] = "qxpfr45d"; users["mama"] = "nf67r"; users["papa"] = "pwr12aa"; users["gosti"] = ""; var l = prompt("Введите свой логин:", "gosti"); var p = prompt("Введите свой пароль:", ""); if (p == users[l]) { alert ("Привет!"); //дальнейшие действия ... } else { alert ("Неверный логин или пароль"); }
С точки зрения клиентского сценария данный пример не представляет практического интереса. Любой желающий может просмотреть код скрипта, увидеть в нем логин и пароль и воспользоваться ими для входа на страницу. Однако, не стоит забывать, что JavaScript используется для написания не только клиентских, но и серверных сценариев, код которых не посылается пользователю, а выполняется на сервере. В этом случае приведенный механизм защиты становится не таким уж и плохим.
У массивов есть несколько полезных методов высшего порядка – forEach, чтобы сделать что-то с каждым элементом, filter – чтобы построить новый массив, где некоторые значения отфильтрованы, map – чтобы построить новый массив, каждый элемент которого пропущен через функцию, reduce – для комбинации всех элементов массива в одно значение.