Всё только о JavaScript

/ Статьи / Массивы в JavaScript

Что такое массивы в JavaScript

Массивы в JavaScript это не совсем то, к чему все привыкли в других языках. Точнее даже совсем не то. Массивы (здесь и далее массивы == массивы в JavaScript) порождаются конструктором Array, наследующим Object. От обычных объектов массивы отличаются тем, что специальным образом оперируют с числовыми свойствами и свойством length.

Существует распространённое ошибочное мнение, что length равно максимальному индексу в массиве плюс 1. Но это лишь частный случай. В общем случае length строго больше максимального индекса в массиве. Например, мы можем самостоятельно менять length.

var a = [1, 2, 3];
a.length = 5;
alert(a.length + '; ' + [0 in a, 1 in a, 2 in a, 3 in a, 4 in a]);    // 5; true,true,true,false,false
// Видим, что length равен 5, хотя элементов в массиве всего 3.

a.length = 1;
alert(a.length + '; ' + [0 in a, 1 in a, 2 in a, 3 in a, 4 in a]);    // 1; true,false,false,false,false
// length уменьшилось и все элементы, индексы которых больше или равны length, были удалены.

Если взять определение объекта в JavaScript

Объект — это неупорядоченное множество пар ключ-значение.

То, в силу того, что массивы те же объекты, можно сказать, что массивы — это неупорядоченное множество пар ключ-значение с особой обработкой числовых ключей и свойства length.

В общем случае невозможно узнать, сколько элементов в массиве, не перебирая их. Но в подавляющем большинстве случаев создаваемые массивы не имеют пропусков, и свойство length у них вручную не изменяется, поэтому length равно количеству элементов в массиве.

Многомерные массивы

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

var a0 = [10, 11, 12];
var a1 = [20, 21, 22];
var a2 = [30, 31, 32];
var a = [a0, a1, a2];
alert(a[0]);  // 10,11,12
alert(a[1]);  // 20,21,22
alert(a[2]);  // 30,31,32

Но не забывайте, что это всё-таки не многомерный массив, а массив массивов. В чём разница: двумерный массив, как частный случай многомерного, это матрица MxN, т.е., грубо говоря, таблица, из M строк и N столбцов. В каждой строке у неё одинаковое количество элементов, равно как и в каждом столбце. В JavaScript иначе, тут в массиве верхнего уровня лежат ссылки на другие произвольные массивы. Они могут быть одинакового размера, могут быть разного, а могут быть вообще не массивами. Многомерный массив — это нечто целое, массив массивов — это множество различных массивов, ссылки на которые лежат ещё в одном массиве.

var a = [
    [1, 2, 3, 4, 5],    // В этом подмассиве у нас пять чисел
    ['a', 'b', 'c'],    // В этом подмассиве три строки
    {foo: 'bar'}        // А тут вообще объект
];
alert(a[0][2]);       // 3
alert(a[1][1]);       // b
alert(a[2].foo);      // bar
alert(a[2]['foo']);   // bar

Тем не менее при аккуратном использовании массив массивов может хорошо выполнять роль многомерного массива.

var a = [
    ['0x0', '0x1', '0x2', '0x3'],
    ['1x0', '1x1', '1x2', '1x3'],
    ['2x0', '2x1', '2x2', '2x3'],
    ['3x0', '3x1', '3x2', '3x3']
];
alert(a[2][1]);   // 2x1
alert(a[3][3]);   // 3x3

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

Как было сказано выше, массивы в JavaScript оперируют специальным образом только с числовыми свойствами и с length. Со всеми остальными свойствами они ведут себя аналогично обычным объектам. Поэтому не следует использовать их в качестве ассоциативных массивов.

// Следующие "ассоциативные массивы" аналогичны  
var a1 = [];
a1.foo = 'bar';

var a2 = new Number();
a2.foo = 'bar';

// Но лучше всё-таки так
var a3 = {};
a3.foo = 'bar';
// Или так
var a4 = {foo: 'bar'};