JavaScript

Объясните пошагово, как работает это выражение

 let n = 10;

[...Array(n + 1).keys()] // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Каким образом работает это выражение?
Nuraly Sembaev
Nuraly Sembaev
31
n равен 10, поэтому сразу упростим до
 [...Array(11).keys()] 
- Array(11) создает новый массив с 11-ю пустыми ячейками.
Если вот так его вызвать в хроме, он покажет вот это:
 (11) [empty × 11] 
Пустой массив, размера 11, имеет свойство .length = 11;
Причем, если пробовать получить то, что хранится в ячейках такого массива, будем получать undefined:
 let x = Array(11); 
console.log(x[0]); // undefined
console.log(x[1]); // undefined
А чем этот "empty" отличается от того, если бы создали массив из 11 ячеек и реально записали во всех ячейках undefined?
 let x = Array(3);
let y = [undefined, undefined, undefined];

console.log(x.hasOwnProperty(1)); // false
console.log(y.hasOwnProperty(1)); // true
У «empty» массива нет индексов, там пустота. JS пофиг, есть индекс или его нет - запросили - не нашел, вернет undefined.
_____________
Почему не new Array(11) ?
Функция Array внутри выглядит примерно так:
 function Array() {
if (!(this instanceof Array)) return new Array(arguments);
//...
}
Т.е. если вызвать его без new, он всё равно сам перевызовет себя через new.
 // Array() или new Array() - одно и то же. 
_____________
итак, имеем пустой массив длины 11.
 .keys() 
Метод массива, который возвращает перебираемый (итерируемый) объект, у которого будут значения от 0 до (length - 1). игнорируя - есть ли в массиве реально этот индекс или нет.

итерируемый объект, значит, что его можно перебрать через for...of
 let x = Array(3).keys();
for (let key of x) {
console.log(key, x[key]);
}
// 0, undefined
// 1, undefined
// 2, undefined
Либо через spread оператор (троеточие), куда-нибудь затолкать его элементы. Например, в другой массив.
 [...Array(3).keys()] // [0, 1, 2] 
Приехали))
А у меня как-раз картошка успела доготовиться)))
Никита Паюк
Никита Паюк
62 360
Лучший ответ
Nuraly Sembaev спасибо за ответ и потраченное на него время) теперь все стало ясно.
Array(n + 1) - возвращает массив длинной n + 1 (или с максимальным индексом n).
.keys() - возвращает итератор, который перебирает ключи массива, в данном случае его индексы от 0 до n.
Таким образом Array.from(Array(n + 1).keys()) вернёт массив [0, ... , n]
Здесь используется выражение ...array, которое выводит все значения массива или итератора в строку, аналогично если ты напишешь array[0], array[1], ... до конца массива.
В данном случае индексы, которые возвращает итератор, помещаются в массив.
[array[0], array[1], ... , array[n]]
Юрий Албахтин
Юрий Албахтин
60 866
Nuraly Sembaev спасибо за ответ!
Это не пошагово это одна синтаксическая конструкция.
Samandar Mirzoali
Samandar Mirzoali
12 593
Nuraly Sembaev 1. что делает Array(n + 1) ? почему не new Array() ?
2. зачем нужен .keys() ?
Samandar Mirzoali >> что делает Array(n + 1) ...
Вызывает функцию Array

>> почему не new Array() ?
Потому что ключевое слово (оператор) new вызывает функцию как конструктор. а в данный момент это не требуется.

>> зачем нужен .keys() ?
Что бы вызвать функцию keys() в контексте какого то объекта (то что идет до оператора точки).