Оператор распространения a.ka. три волшебные точки расширяют итерацию на место. Итерируемый объект может быть массивом, строкой или набором.

Оператор распространения используется в трех основных случаях: при вызове функции при создании литерала массива и создании литерала объекта.

Представьте, что вы хотите найти максимальное число в массиве.

const randomArray=[5,4,8,200,-4]

До того, как функция синтаксиса оператора распространения была добавлена ​​в javascript - до ES6 - мы использовали бы что-то вроде:

Math.max.apply(null, randomArray)

Однако есть способ получше Math.max(...randomArray).

Это работает, потому что оператор распространения распаковывает элементы массива и передает их методу max один за другим.

Другой вариант использования оператора - объединение или объединение массивов. И если вы сделаете следующее

const fullTimeEmployees = ["Dave", "Anna", "John"];
const partTimeEmployees = ["Samantha", "Peter", "Donald"];
const allEmployees = [fullTimeEmployees, partTimeEmployees];
console.log(allEmployees);

У вас получится вложенный массив

[[ ‘Dave’, ‘Anna’, ‘John’ ], [ ‘Samantha’, ‘Peter’, ‘Donald’ ]]

Итак, мы можем использовать один из самых простых способов объединения массивов, который… как вы уже догадались, это оператор распространения.

console.log([...fullTimeEmployees, ...partTimeEmployees]);

И результат такой, как ожидалось

[‘Dave’, ‘Anna’, ‘John’, ‘Samantha’, ‘Peter’, ‘Donald’ ]

Я знаю, что мы можем добиться того же, используя метод concat
const allEmployees = fullTimeEmployees.concat(partTimeEmployees);

Кстати, мы также можем разбить строку на составляющие ее символы, используя оператор распространения следующим образом:

const spreadableString=”This is awesome”

[...spreadableString] даст нам

[
‘T’, ‘h’, ‘i’, ‘s’,
‘ ‘, ‘i’, ‘s’, ‘ ‘,
‘a’, ‘w’, ‘e’, ‘s’,
‘o’, ‘m’, ‘e’
]

Это неудивительно, поскольку строки также являются повторяемыми.

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

let languagesInChina = ["Mandarin", "Cantonese"];
let copyOflanguagesInChina = languagesInChina;
copyOflanguagesInChina.push("Hunanese");
console.log(languagesInChina);

Поскольку и languagesInChina, и copyOflanguagesInChina ссылаются на один и тот же объект, они оба будут содержать обновленную версию на трех языках.

['Mandarin', 'Cantonese', 'Hunanese' ]

Но на помощь приходит оператор распространения, и все, что нам нужно сделать, это

let copyOflanguagesInChina = [...languagesInChina];

Теперь наш исходный массив остается неизменным - уф, это было близко.

Примечание. Этот вариант использования оператора весьма полезен, например, при работе с состояниями React. Поскольку мы не хотим изменять состояние, копирование его, как описано выше, - один из лучших способов.

Однако помните, что оператор распространения не подходит для копирования многомерных массивов.

Другой вариант использования - изменить Nodelist, который представляет собой объект, подобный массиву, на настоящий массив, который использует такие методы, как map() и filter().

Допустим, мы хотим изменить атрибут src третьего изображения "на лету". Вот что мы делаем:

const imgEls = [...document.querySelectorAll("img")];
const thirdImage = imgEls.map((anImage, i) => {
if (i === 2) {
anImage.setAttribute("src","https://images.unsplash.com/photo-1601327391865-398708fcb4ba?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTV8fHNwcmVhZCUyMHdpbmdzfGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=60");
}
})
console.log(thirdImage);

Итак, наше третье изображение теперь не пустое. См. Ниже снимок экрана консоли разработчика.

Этот пример немного надуманный, но я надеюсь, что он хорошо иллюстрирует вариант использования.

Последний вариант использования - это то, с чем я столкнулся, когда работал над этим проектом рецептов React, где мне нужно было передавать значения объекта в качестве свойств. Вы можете себе представить, как больно делать что-то вроде

return <Recipe key={recipe.id} id={recipe.id} name={recipe.name}
servings={recipe.servings}
cookTime = { recipe.cookTime }
instructions={recipe.instructions}/>

Вместо этого сделайте это, и вы все разобрались

return <Recipe key={recipe.id} {...recipe} />

На мой взгляд, оператор спреда - это то, что когда вы начинаете его использовать, вы задаетесь вопросом, как было время, когда его не существовало. Сочувствую разработчикам до 2015 года.

Спасибо за чтение и не стесняйтесь комментировать.