Какая разница между массивами (2) и [undefined, undefined]? - программирование
Подтвердить что ты не робот

Какая разница между массивами (2) и [undefined, undefined]?

[undefined, undefined, undefined].map(function(val, i) { return i });

возвращает [0, 1, 2], а

Array(3).map(function(val, i) { return i });

возвращает [undefined, undefined, undefined].

Почему?

4b9b3361

Ответ 1

В первом случае вы определили и инициализировали новый массив с тремя значениями undefined, тогда как во втором случае у вас есть только определенный массив с возможная длина 3.

new Array(3) - это то же самое, что и вы:

var arr = [];
arr.length = 3;

В результате, если свойство .length неявно определено, метод .map() может выполнять итерацию по массиву, выделенному в памяти, который в основном содержит нулевые определенные элементы (т.е. чисто пустые).

Ответ 2

Вы объявляете указатели на undefined объекты, записывающие undefined. Таким образом, [undefined] создает массив указателя на undefined. new Array(3) создает массив указателей undefined, которые не зацикливаются на методах прототипа массива (включая .map).

Справочник по MDN. Переменная undefined фактически присваивает значение, даже если оно указывает на undefined.

Ответ 3

Array(3) просто берет пустой массив и вручную назначает ему длину:

> a = []
[]
> a.length = 3
3
> a
[ , ,  ]

Это не то же самое, что вручную создавать массив, содержащий элементы undefined:

> a = [undefined, undefined, undefined]
[ undefined, undefined, undefined ]


документация MDN для Array точно объясняет, что происходит:

Если единственным аргументом, переданным конструктору Array, является целое число от 0 до 2 32 -1 (включительно), новый пустой массив JavaScript и его длина будут установлены на это число. Если аргументом является любое другое число, генерируется исключение RangeError.

Итак, массив инициализируется пустым массивом []. Это объясняет, почему map не обрабатывает какие-либо элементы массива, потому что их нет.


Несколько примеров могут помочь. Когда массив инициализируется с помощью Array(3), он пуст, поэтому map не имеет ничего для перебора:

> Array(3)
    .map(function(val, i) { console.log(i); return i; });
[ , ,  ]

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

> [undefined, undefined, undefined]
    .map(function(val, i) { console.log(i); return i; });
0
1
2
[ 0, 1, 2 ]

Ответ 4

Как упоминалось @VisioN, Array (3) определен, но неинициализирован. Интересно, что вы можете передать неинициализированный массив через Array.apply и инициализировать его. Я использовал это для заполнения массивов:

Array.apply(null, Array(3)).map(function(val,i) { return i; });
// [0, 1, 2]

Ответ 5

<script type="text/javascript">
 test();
 test2();

function test() {
   [undefined, undefined, undefined].map(function(val, i) { console.log("un: " + val + "/" + i); return i; });
 }

 function test2() {
    Array(3).map(function(val, i) { console.log("no: " + val + "/" + i); return i; });
 }
</script>
Функция

test() возвращает:

un: undefined/0 un: undefined/1 un: undefined/2

Функция test2() не возвращает значение;

  • test() у вас есть объект, содержащий 3 значения (undefined)
  • test2() имеет пустой массив длиной 3