Для понимания того, что такое пропуски в массивах, необходимо прочитать и осознать статью про undefined в JavaScript.
Как и любой другой объект, массив можно создать вызовом конструктора с ключевым словом new
. Например,
var a1 = new Array(); // Пустой массив
var a2 = new Array(5); // Пустой массив с length равным 5
var a3 = new Array(1, 2, 3); // Массив с тремя элементами 1, 2 и 3
Но делать этого не стоит.
Во-первых, поведение этого конструктора неоднозначно. В общем случае конструктор создаёт массив с элементами, переданными ему в аргументах. Но невозможно с его помощью создать массив с одним целочисленным элементом. Т.к. в этом случае будет создан пустой массив с length
, равным единственному переданному аргументу.
А во-вторых, в JavaScript есть более краткая и более удобная литеральная нотация для создания массивов: квадратные скобки.
var a1 = []; // Пустой массив
var a2 = [5]; // Массив с одним элементом 5
var a3 = [1, 2, 3]; // Массив с тремя элементами 1, 2 и 3
В JScript, т.е. во всех версиях Internet Explorer, есть одна неприятная особенность — если конструктору в качестве элемента передать undefined
, то элемент создан не будет.
var a = [1, undefined, 3, undefined, 5]; // Аналогично и в случае a = new Array(1, undefined, 3, undefined, 5)
alert(a.length + '; ' + [0 in a, 1 in a, 2 in a, 3 in a, 4 in a]);
// Во всех браузерах кроме IE этот код выведет 5; true,true,true,true,true
// В IE будет 5; true,false,true,false,true
Возможно такое поведение объясняется не слишком большой разницей между отсутствием свойства и свойством, равным undefined
. Однако эту особенность следует иметь в виду, т.к. она может привести к непредсказуемым последствиям. Например, при использовании методов forEach
/map
/filter
/reduce
.
При создании массива литеральной нотацией можно делать пропуски в списке элементов. Пропущенный элемент массива увеличивает свойство length
и индексы последующих элементов. Везде, кроме JScript, пропущенным элементом считается запятая перед которой отсутствует элемент, т.е. запятая в начале списка элементов или сразу после другой запятой. В JScript (т.е. в IE) поведение отличается ровно на единицу — учитывается пропуск после последней запятой. Поэтому в целях кроссбраузерности кода не рекомендуется заканчивать описание массива пропуском.
var a = [1, , 3, , 5];
alert(a.length + '; ' + [0 in a, 1 in a, 2 in a, 3 in a, 4 in a]);
// 5; true,false,true,false,true
a = [, , 1, , ];
alert(a.length + '; ' + [0 in a, 1 in a, 2 in a, 3 in a, 4 in a]);
// В IE 5; false,false,true,false,false
// в остальных браузерах 4; false,false,true,false,false