«Uncaught TypeError: функция не повторяется» с использованием ... в [], но в {} это работает ...? - PullRequest
1 голос
/ 26 мая 2020

Рассмотрим этот простой пример:

const someFunction = () => [1, 2, 3];

Теперь

const myArr = [...someFunction];

дает ошибку времени выполнения, что понятно, поскольку функции не повторяются. Итак,

const myArr = [...someFunction()];

- правильная реализация.

Однако

const myObj = {...someFunction};

приводит к {} и не вызывает ту же ошибку.

Пожалуйста, помогите мне понять это поведение и почему последний случай не вызывает ту же ошибку.

Ответы [ 2 ]

5 голосов
/ 26 мая 2020

Ваш {...someFunction} работает, потому что функции являются объектами, а ... в литерале объекта предназначен для работы с объектами, а не с итерациями: он берет свои собственные перечисляемые свойства и помещает их в создаваемый объект. По умолчанию функции не имеют собственных перечислимых свойств, поэтому вы получите пустой объект, но если вы добавили свойство к функции, а затем использовали ... в литерале объекта, это свойство будет скопировано в новый объект:

const someFunction = () => [1, 2, 3];
someFunction.myProperty = "foo";

const obj = {...someFunction};

console.log(obj.myProperty);   // "foo"
console.log(Object.keys(obj)); // ["myProperty"]

... означает разные вещи в разных контекстах. ... в литерале массива отличается от ... в литерале объекта. В литерале массива, как вы говорите, используется итерация для создания записей для массива, но это неверно в литерале объекта. ... в литерале объекта - это свойство spread , добавленное в ES2018. Он вообще не полагается на итерацию; вместо этого он использует внутреннюю операцию под названием [[OwnPropertyKeys]] , чтобы найти ключи свойств для копирования из исходного объекта, а затем копирует их (это во внутренней операции CopyDataProperties ).

3 голосов
/ 26 мая 2020

Javascript функций являются объектами, и вы распределяете свойства функции (объекта).

Вы можете взять функцию и добавить такое значение:

someFunction.hello = 'world';
console.log(someFunction.hello);
...