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

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

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

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


person granmoe    schedule 13.10.2018    source источник
comment
Правила оператора расширения для массивов и литералов объектов различаются. При использовании с объектными литералами не требуется, чтобы оператор распространения применялся к итерируемым объектам: github .com/tc39/proposal-object-rest-spread   -  person jrook    schedule 13.10.2018


Ответы (1)


В объектных литералах spread operator < strong>копирует собственные перечисляемые свойства из предоставленного объекта в новый объект. Таким образом, в ваших примерах ни одна из предоставленных «сущностей» оператору распространения не имеет перечисляемых свойств.

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

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

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

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

person Akrion    schedule 13.10.2018
comment
Отличное объяснение! Спасибо :-) Знание того, что использование оператора расширения в литерале объекта копирует перечисляемые свойства операнда, тогда как его использование в литерале массива просто пытается вызвать итератор операнда, делает поведение примеров, которые я привел, вполне понятным. - person granmoe; 14.10.2018