Поэтому я задал этот вопрос в своей команде. Что будет на выходе такого кода?
Довольно хорошо, правда? Если вы хотите проверить кого-то, насколько хорошо человек разбирается в спреде, и посмотреть, знает ли он, что такое массивы в 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
. Давай попробуем:
Я прибил это?
Я сделал. Но почему это заняло у меня так много времени? Потому что я сначала посмотрел на спред и массивы, и это отвлекло меня от правильного взгляда. Но это хорошо. Всегда читайте документы, дети.