Поэтому я задал этот вопрос в своей команде. Что будет на выходе такого кода?

Довольно хорошо, правда? Если вы хотите проверить кого-то, насколько хорошо человек разбирается в спреде, и посмотреть, знает ли он, что такое массивы в JS, хороший вопрос. Вывод будет выглядеть следующим образом:

Почему? Потому что Array — это просто объект в JavaScript. С множеством дополнительных методов здесь и там, но под капотом это Object.

И это подводит нас к еще одной интересной теме. Массивы лайков. Что это за фигня? По сути, это то, что мы получаем, когда распространяем массив на объекты. Мы обрезаем все хорошее, например .map(), .reduce() и так далее, и оставляем только то, что есть, ключи и значения. Кроме одного. Ребята, а где length?

Например, Array.from берет объект, похожий на массив, и создает из него массив. И вы можете увидеть такой код: Array.from({ length: 10 }) и все. Так что самое главное для Array-like — это length , а спред его обрезал. Где это и как мы можем эмулировать поведение, написав свои собственные классы?

Хорошо, а что я пробовал?

Я тестировал его на Object.keys() и for..in цикле. Еще нет length

Но при этом этот код выдал true

Вот реальная цитата одного из наших разработчиков:

потому что это похоже на внутреннее свойство «класса» массива. его обновление зависит от содержимого массива. это не часть массива

Итак, я могу написать класс? Это может иметь какое-то свойство, которое не будет распространяться? Если свойство определено в конструкторе, то оно не распространяется? Мне это не кажется логичным, но давайте напишем класс.

Выглядит неплохо?

Каков результат?

Может быть, я сделал это неправильно? Давайте попробуем это:

Такой же

Старая школа?

Посмотрим…

Кажется, это не имеет значения. И я думаю, это потому, что это все еще Object.

Ладно, может быть, length — это getter/setter, а не свойство?

Посмотрим…

Ага! Общая победа. Здесь нет length, дело закрыто! Ждать…

Решение

Давайте подробнее рассмотрим, что именно делает спред.

Он копирует собственные перечисляемые свойства из предоставленного объекта в новый объект.

Что такое перечислимое?

Перечисляемые свойства — это те свойства, внутренний флаг перечисления которых установлен в значение true, что является значением по умолчанию для свойств, созданных с помощью простого присваивания или через инициализатор свойства (свойства, определенные с помощью Object.defineProperty и такие перечисляемые значения по умолчанию имеют значение false).

Хорошо, тогда, может быть, length не является перечислимым? Не распространяется, не появляется в for..in и в Object.keys . Давай попробуем:

Я прибил это?

Я сделал. Но почему это заняло у меня так много времени? Потому что я сначала посмотрел на спред и массивы, и это отвлекло меня от правильного взгляда. Но это хорошо. Всегда читайте документы, дети.