В JavaScript, почему любое значение может быть распространено в объекте, но не в массиве?

1

Распространение любого "пустого" значения в объекте является допустимым (не выдает ошибку, а вместо этого становится своего рода no-op):

{
  ...undefined,
  ...null,
  ...false,
  ...true,
  ...'',
  ...{},
  ...[],
  ...Symbol(),
  ...() => {},
} // evaluates to {}

Но то же самое в массиве вызывает ошибку для всех вышеперечисленных значений, кроме '' и []. В сообщении об ошибке указано, что значения, которые не работают, не являются итерабельными, однако они явно повторяются в том смысле, что они могут быть распространены в объект. Разумеется, интуитивно понятно, что строки, массивы и объекты могут быть преобразованы в пары entries/key-value при распространении в объект и преобразовываться в значения при распространении в массив, но даже в этом случае, почему записи всех этих значения будут итерабельными, но значения не будут? Если записи итерабельны, не должны ли значения быть такими же? Это просто причуда разных движков JavaScript? Что здесь происходит?

  • 0
    Правила для оператора распространения для массивов и литералов объектов различны. При использовании с объектными литералами не требуется применять оператор распространения к итерируемым объектам: github.com/tc39/proposal-object-rest-spread
Теги:
iterator
spread-syntax
iterable

1 ответ

1
Лучший ответ

В объектных литералах spread operator копирует собственные перечислимые свойства из предоставленного объекта на новый объект. Поэтому в ваших примерах ни один из предоставленных "сущностей" оператору спреда не имеет перечислимых свойств.

С массивами синтаксис распространения применяется только к итерабельным объектам.

Или объекты, которые реализуют протокол итератора... значение:

Объект (или один из объектов в цепочке прототипов) должен иметь свойство с ключом @@iterator, доступным через константу Symbol.iterator

Основные объекты, которые это делают:

  • 0
    Отличное объяснение! Спасибо :-) Зная, что использование оператора распространения внутри литерала объекта копирует перечислимые свойства операнда, тогда как использование его в литерале массива просто пытается вызвать итератор операнда, делает поведение примеров, которые я дал, имеет смысл.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню