Массивы (объект Array)

Массивы JavaScript используются для хранения множества значений в одной переменной.


var cars = ["Saab", "Volvo", "BMW"]; 

Что такое массив?

Массив — это особая переменная, которая может хранить более одного значения за раз.

Если у вас есть список неких значений (например, список марок автомобилей), то сохранение их в отдельных переменных будет выглядеть следующим образом:


var car1 = "Saab";
var car2 = "Volvo";
var car3 = "BMW"; 

Все вроде бы нормально, но что если вам нужно пройтись в цикле по маркам автомобилей и найти какую-то конкретную марку? И при этом у вас есть не 3, а 300 автомобилей?

В этом случае вам поможет массив!

Массив позволяет хранить множество значений под одним именем, и вы можете получить доступ к значению по его индексу.

Создание массива

Самый простой способ создать массив в JavaScript это определить переменную-массив, присвоив ей нужные значения в виде константы-массива:


var имя_массива = [элемент1, элемент2, ...];

Пример:


var cars = ["Saab", "Volvo", "BMW"]; 

Пробелы и перевод строки не имеют значения. Декларация массива может занимать и несколько строк:


var cars = [
     "Saab",
     "Volvo",
     "BMW"
];

Внимание! Запятая после последнего элемента (например, "BMW",) в разных браузерах работает по разному. Например, в IE 8 и более ранних версиях это приведет к ошибке.

Использование ключевого слова new

В следующем примере также создается массив и присваиваются значения:


var cars = new Array("Saab", "Volvo", "BMW"); 

Оба примера делают одно и то же. Обычно использовать конструкцию new Array() нет необходимости. Для простоты, читабельности и большей скорости исполнения скрипта лучше использовать первый способ создания массива (при помощи константы-массива).

Доступ к элементам массива

Чтобы получить доступ к элементу массива, необходимо обратиться к нему по его индексу.

В следующем выражении извлекается значение первого элемента массива cars:


var name = cars[0];

В следующем выражении изменяется первый элемент массива cars:


cars[0] = "Opel"; 

Пример:


var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars[0]; 

Обратите внимание, что первый элемент массива имеет индекс [0], второй [1] и т.д. Индексация массивов всегда начинается с 0.

Кроме этого JavaScript допускает использование всего массива, обратившись к нему по его имени:


var cars = ["Saab", "Volvo", "BMW"];
document.getElementById("demo").innerHTML = cars; 

Массивы — это объекты

Массивы — это особый тип объектов. Оператор typeof для массивов возвращает тип "object".

Однако JavaScript массивы лучше описывать как массивы.

Массивы для доступа к "элементам" используют цифровые номера. В следующем примере person[0] возвращает значение "Иван":


var person = ["Иван", "Петров", 46];

Объекты для доступа к своим "подпеременным" используют их имена. В следующем примере person.firstName возвращает значение "Иван":


var person = {firstName:"Иван", lastName:"Петров", age:46};

Элементами массива могут быть объекты

Переменные JavaScript могут быть объектами. Массивы — особый вид объектов.

Благодаря этому, массивы могут хранить переменные разных типов.

Помимо примитивных значений в массивах могут храниться объекты, функции и другие массивы:


myArray[0] = Date.now;
myArray[1] = myFunction;
myArray[2] = myCars;

Свойства и методы массивов

Реальная сила массивов JavaScript заключается в их встроенных свойствах и методах:


var x = cars.length;   // Свойство length возвращает кол-во элементов
var y = cars.sort();   // Метод sort() сортирует массив

О методах массивов будет рассказано в следующей главе этого учебника.

Свойство length

Свойство массива length возвращает длину массива (количество его элементов).


var fruits = ["Банан", "Апельсин", "Яблоко", "Манго"];
fruits.length;         // длина массива fruits равна 4

Внимание! Значение, возвращаемое свойством length, всегда на единицу больше, чем самый большой индекс в массиве.

Обращение к первому элементу массива

Пример:


fruits = ["Banana", "Orange", "Apple", "Mango"];
var first = fruits[0];

Обращение к последнему элементу массива

Пример:


fruits = ["Banana", "Orange", "Apple", "Mango"];
var last = fruits[fruits.length - 1];

Обход элементов массива

Лучший способ обойти все элементы массива, это воспользоваться оператором цикла for:

var fruits, text, fLen, i; fruits = ["Банан", "Апельсин", "Яблоко", "Манго"]; fLen = fruits.length; text = "<ul>"; for (i = 0; i < fLen; i++) { text += "<li>" + fruits[i] + "</li>"; }

Также, можно воспользоваться функцией Array.forEach():


var fruits, text;
fruits = ["Banana", "Orange", "Apple", "Mango"];

text = "<ul>";
fruits.forEach(myFunction);
text += "</ul>";

function myFunction(value) {
  text += "<li>" + value + "</li>";
}

Добавление элементов в массив

Самый простой способ добавить новый элемент в массив это воспользоваться методом push:


var fruits = ["Банан", "Апельсин", "Яблоко", "Манго"];
fruits.push("Лимон");                // добавим новый элемент в массив fruits

Также, новый элемент можно добавить при помощи свойства length:


var fruits = ["Банан", "Апельсин", "Яблоко", "Манго"];
fruits[fruits.length] = "Лимон";     // добавим новый элемент в массив fruits

ВНИМАНИЕ! Добавление элементов с большими индексами может создать в массиве "дыры" со значением undefined.

В следующем примере в массиве fruits будут созданы "дыры" по индексам [4] и [5]:


var fruits = ["Банан", "Апельсин", "Яблоко", "Манго"];
fruits[6] = "Лимон";     // добавим новый элемент в массив fruits

Ассоциативные массивы

Во многих языках программирования существует особый тип массивов, в которых в качестве индексов используются имена. Такие массивы называются ассоциативными.

JavaScript не поддерживает ассоциативные массивы.

В JavaScript массивы всегда используют цифровые индексы.


var person = [];
person[0] = "Иван";
person[1] = "Петров";
person[2] = 46;
var x = person.length;         // person.length вернет 3
var y = person[0];             // person[0] вернет "Иван"

ВНИМАНИЕ!! Если вы в качестве индексов укажете имена, то JavaScript переопределит такой массив в стандартный объект. После этого свойства и методы массива будут возвращать неверный результат.


var person = [];
person["firstName"] = "Иван";
person["lastName"] = "Петров";
person["age"] = 46;
var x = person.length;         // person.length вернет 0
var y = person[0];             // person[0] вернет undefined

Разница между массивами и объектами

В JavaScript массивы для доступа к элементам используют цифровые индексы. Объекты используют индексы-имена.

Таким образом, массивы — это особый тип объектов с цифровой индексацией элементов.

Когда использовать массивы, а когда объекты

  • JavaScript не поддерживает ассоциативные массивы.
  • Если вам нужно, чтобы имена элементов были строками, то используйте объекты.
  • Если вам нужно, чтобы имена элементов были цифрами, то используйте массивы.

Избегайте конструкции new Array()

Нет никакой необходимости для создания массива использовать встроенный JavaScript конструктор массивов new Array().

Вместо этого используйте оператор [].

В следующем примере два выражения создают новый пустой массив с именем points:


var points = new Array();  // Плохо
var points = [];           // Хорошо

Ключевое слово new только усложняет код. Также, оно может привести к неожиданным результатам:


var points = new Array(40, 100);  // Создается массив с двумя элементами (40 и 100)

Но что если из декларации убрать всего один элемент?


var points = new Array(40);       // Создается массив с 40 элементами типа undefined!!!!!

Как распознать массив

Обычно возникает вопрос: Как я узнаю, что переменная является массивом?

Проблема состоит в том, что в JavaScript для массивов оператор typeof возвращает тип "object":


var fruits = ["Банан", "Апельсин", "Яблоко", "Манго"];
typeof fruits;             // вернет object

Оператор typeof возвращает тип "object", потому что в JavaScript массив это объект. Как же тогда быть?

Решение №1:

Чтобы решить эту проблему в ECMAScript 5 определяется новый метод Array.isArray():


Array.isArray(fruits);     // вернет true

Но здесь возникает другая проблема: ECMAScript 5 не поддерживается в старых браузерах.

Решение №2:

Можно определить такую собственную функцию isArray():


function isArray(x) {
    return x.constructor.toString().indexOf("Array") > -1;
}

Эта функция всегда возвращает true, если в ее параметре передан массив. Вернее, она возвращает true, если в прототипе объекта есть слово "Array".

Решение №3:

Оператор instanceof возвращает true, если объект был создан при помощи заданного конструктора:


var fruits = ["Банан", "Апельсин", "Яблоко", "Манго"];

fruits instanceof Array     // вернет true