Разница между массивом (n) и массивом (n).fill?

Я заметил, что если:

Array(n).map(() => console.log('test'))

Однако, если я это сделаю:

Array(n).fill().map(() => console.log('test'))

Я получаю test распечатанный n раз.

Почему это так? Если я сделаю Array(n).length, я вернусь n.

Я заметил в REPL, что Array(5) возвращает:

[ , , , , ]

В то время как Array(5).fill() возвращает:

[ undefined, undefined, undefined, undefined, undefined ]

В обоих случаях typeof любой элемент массива === undefined.

Итак, что происходит?

Ответ 1

map работает только с определенными целыми свойствами массива. Array(n) не задает целочисленные свойства, а Array(n).fill() -. Там существует разница между отсутствием свойства и существующим свойством, значение которого undefined.

Array(n) устанавливает свойство length для массива, но он не устанавливает никаких свойств. Объект массива не имеет целочисленных свойств.

.fill устанавливает все целочисленные свойства для массива от нуля до единицы меньше length. Когда вы выполняете Array(n), вы устанавливаете свойство length для нового aray, а затем .fill() определяет и устанавливает каждое целочисленное свойство до n-1. Массив, созданный Array(n).fill(), имеет свойства, определенные до length - 1. (Свойства имеют значение undefined, потому что вы не передали аргумент fill, но они существуют.)

В pracitcal терминах вы можете увидеть разницу, если вы делаете Object.keys(Array(4)) (пустой массив) по сравнению с Object.keys(Array(4).fill()) (список строк "0" до "3"). В первом случае свойства не существуют; во втором случае они делают.

Ответ 2

Array(n) создает новый массив размера n, содержимое не было определено.

Array(n).fill() создает массив размера n, где каждый элемент установлен на все, что вы передали в fill или undefined в вашем случае, поскольку вы ничего не передали.

Array(n).fill('test') создает массив размером n, заполненный "тестом".