Кратко
СкопированоСпред-синтаксис (spread) . позволяет передавать итерируемые коллекции (например, массивы или строки) как список аргументов функции или добавлять содержащиеся в них элементы в новый массив.
Спред применятся и для объектов, чтобы копировать пары ключ-значение из одного объекта в другой.
Пример
СкопированоПри вызове функции использовать значения из массива как аргументы:
function multiplyThreeNumbers(a, b, c) { return a * b * c}const nums = [1, 2, 3]console.log(multiplyThreeNumbers(...nums))// 6
function multiplyThreeNumbers(a, b, c) {
return a * b * c
}
const nums = [1, 2, 3]
console.log(multiplyThreeNumbers(...nums))
// 6
В массиве скопировать элементы из другого массива в новый:
const donor = ['это', 'старые', 'значения']const newArray = [...donor, 1, true, 'мама']console.log(newArray)// ['это', 'старые', 'значения', 1, true, 'мама']
const donor = ['это', 'старые', 'значения']
const newArray = [...donor, 1, true, 'мама']
console.log(newArray)
// ['это', 'старые', 'значения', 1, true, 'мама']
У объекта скопировать свойства из другого объекта в новый:
const persona = { name: 'Иван', lastName: 'Объектов'}const userData = { ...persona, username: 'killer3000' }console.log(userData)// {// name: 'Иван',// lastName: 'Объектов',// username: 'killer3000'// }
const persona = { name: 'Иван', lastName: 'Объектов'}
const userData = { ...persona, username: 'killer3000' }
console.log(userData)
// {
// name: 'Иван',
// lastName: 'Объектов',
// username: 'killer3000'
// }
Как понять
СкопированоСпред-синтаксис легче всего изучать на примерах. Есть три контекста, в которых он применяется.
При вызове функции
СкопированоЧасто встречается ситуация, когда мы хотим использовать данные из итерируемой коллекции в качестве аргументов функции. Чаще всего такая коллекция — массив. Если функция не умеет принимать массив аргументом, то придётся доставать элементы вручную:
function multiplyThreeNumbers(a, b, c) { return a * b * c}const nums = [1, 2, 3]console.log(multiplyThreeNumbers(nums[0], nums[1], nums[2]))// 6
function multiplyThreeNumbers(a, b, c) {
return a * b * c
}
const nums = [1, 2, 3]
console.log(multiplyThreeNumbers(nums[0], nums[1], nums[2]))
// 6
Если элементов становится больше, доставать значения вручную становится неудобно. Чтобы решить эту проблему, в старых версиях языка использовали метод apply. Этот метод принимает первым аргументом значение this, а вторым — список аргументов для вызова функции:
function multiplyThreeNumbers(a, b, c) { return a * b * c}const nums = [1, 2, 3]console.log(multiplyThreeNumbers.apply(null, nums))// 6
function multiplyThreeNumbers(a, b, c) {
return a * b * c
}
const nums = [1, 2, 3]
console.log(multiplyThreeNumbers.apply(null, nums))
// 6
Такой синтаксис сложно читается, его нельзя использовать при создании объектов с помощью конструктора new. Его упростили до спред-синтаксиса. В этом случае элементы как бы выкладываются из списка в нужном порядке:
function multiplyThreeNumbers(a, b, c) { return a * b * c}const nums = [1, 2, 3]console.log(multiplyThreeNumbers(...nums))// 6
function multiplyThreeNumbers(a, b, c) {
return a * b * c
}
const nums = [1, 2, 3]
console.log(multiplyThreeNumbers(...nums))
// 6
Если в массиве будет больше элементов, чем параметров функции, то будут использованы только те элементы, которые идут первыми по порядку:
function multiplyThreeNumbers(a, b, c) { return a * b * c}const nums = [1, 2, 3, 5, 6]console.log(multiplyThreeNumbers(...nums))// 6
function multiplyThreeNumbers(a, b, c) {
return a * b * c
}
const nums = [1, 2, 3, 5, 6]
console.log(multiplyThreeNumbers(...nums))
// 6
При создании массивов с помощью литерала []
СкопированоСпред-синтаксис решает задачу создания нового массива с использованием данных из другого массива. Без него неудобно создавать массив, который содержит элементы другого. Приходится использовать методы массива, например, concat:
const watchedMovies = ['Rocky', 'Terminator 2', 'The Matrix']const watchedVideos = ['Rick&Morty', 'lofi hip hop radio'].concat(watchedMovies)console.log(watchedVideos)// ['Rick&Morty', 'lofi hip hop radio', 'Rocky', 'Terminator 2', 'The Matrix']
const watchedMovies = ['Rocky', 'Terminator 2', 'The Matrix']
const watchedVideos = ['Rick&Morty', 'lofi hip hop radio'].concat(watchedMovies)
console.log(watchedVideos)
// ['Rick&Morty', 'lofi hip hop radio', 'Rocky', 'Terminator 2', 'The Matrix']
Спред решает эту проблему лучше:
const watchedMovies = ['Rocky', 'Terminator 2', 'The Matrix']const watchedVideos = ['Rick&Morty', 'lofi hip hop radio', ...watchedMovies]console.log(watchedVideos)// ['Rick&Morty', 'lofi hip hop radio', 'Rocky', 'Terminator 2', 'The Matrix']
const watchedMovies = ['Rocky', 'Terminator 2', 'The Matrix']
const watchedVideos = ['Rick&Morty', 'lofi hip hop radio', ...watchedMovies]
console.log(watchedVideos)
// ['Rick&Morty', 'lofi hip hop radio', 'Rocky', 'Terminator 2', 'The Matrix']
Таким образом можно создать копию существующего массива:
const watchedMovies = ['Rocky', 'Terminator 2', 'The Matrix']const myWatchedMovies = [...watchedMovies]
const watchedMovies = ['Rocky', 'Terminator 2', 'The Matrix']
const myWatchedMovies = [...watchedMovies]
Или склеить несколько массивов в один:
const movies = ['Rocky', 'Terminator 2', 'The Matrix']const series = ['Prison Break', 'Rick&Morty', 'Lost']const watched = [...movies, ...series]// [// 'Rocky',// 'Terminator 2',// 'The Matrix',// 'Prison Break',// 'Rick&Morty',// 'Lost'// ]
const movies = ['Rocky', 'Terminator 2', 'The Matrix']
const series = ['Prison Break', 'Rick&Morty', 'Lost']
const watched = [...movies, ...series]
// [
// 'Rocky',
// 'Terminator 2',
// 'The Matrix',
// 'Prison Break',
// 'Rick&Morty',
// 'Lost'
// ]
Пример поведения с уровнем вложенности больше одного:
const users = [{ name: 'Иван', lastName: 'Объектов' }]const copyUsers = [...users]copyUsers[0].name = 'Николай'console.log(users[0])// { name: 'Николай', lastName: 'Объектов' }
const users = [{ name: 'Иван', lastName: 'Объектов' }]
const copyUsers = [...users]
copyUsers[0].name = 'Николай'
console.log(users[0])
// { name: 'Николай', lastName: 'Объектов' }
При создании объекта с помощью литерала {}
СкопированоПо аналогии с массивами, спред-синтаксис решает проблему копирования свойств в новый объект. В версии языка без спреда для копирования использовался метод Object, который принимал два объекта — куда копировать свойства и откуда:
const person = { name: 'Иван', lastName: 'Объектов' }const userData = Object.assign({ username: 'killer3000' }, person)console.log(userData)// {// name: 'Иван',// lastName: 'Объектов',// username: 'killer3000'// }
const person = { name: 'Иван', lastName: 'Объектов' }
const userData = Object.assign({ username: 'killer3000' }, person)
console.log(userData)
// {
// name: 'Иван',
// lastName: 'Объектов',
// username: 'killer3000'
// }
Спред упрощает код и делает его читабельнее:
const person = { name: 'Иван', lastName: 'Объектов' }const userData = { username: 'killer3000', ...person }console.log(userData)// {// name: 'Иван',// lastName: 'Объектов',// username: 'killer3000'// }
const person = { name: 'Иван', lastName: 'Объектов' }
const userData = { username: 'killer3000', ...person }
console.log(userData)
// {
// name: 'Иван',
// lastName: 'Объектов',
// username: 'killer3000'
// }
Если свойства в новом и старом объекте совпадают, то будет использоваться значение свойства, которое шло последним:
const person = { name: 'Иван', lastName: 'Объектов' }const userData = { name: 'Николай', ...person }console.log(userData)// { name: 'Иван', lastName: 'Объектов' }
const person = { name: 'Иван', lastName: 'Объектов' }
const userData = { name: 'Николай', ...person }
console.log(userData)
// { name: 'Иван', lastName: 'Объектов' }
Если поставить спред в начало, то будет использоваться новое имя:
const person = { name: 'Иван', lastName: 'Объектов' }const userData = { ...person, name: 'Николай' }console.log(userData)// { name: 'Николай', lastName: 'Объектов' }
const person = { name: 'Иван', lastName: 'Объектов' }
const userData = { ...person, name: 'Николай' }
console.log(userData)
// { name: 'Николай', lastName: 'Объектов' }
На практике
Скопированосоветует
Скопировано🛠 Спред на объектах используют в библиотеке React. Программист может передать в функцию объект с произвольными свойствами, но мы хотим запретить устанавливать некоторые из них. В этом случае создаётся новый объект, в который сначала копируются присланные значения, а потом значения «запрещённых» свойств. В этом случае даже если запрещённое свойство было передано, оно будет перезаписано:
function Headline(props) { const filteredProps = {...props, ariaHidden: false} return createElement('h1', filteredProps, 'Текст заголовка')}
function Headline(props) {
const filteredProps = {...props, ariaHidden: false}
return createElement('h1', filteredProps, 'Текст заголовка')
}
На собеседовании
Скопировано отвечает
СкопированоRest- и spread-операторы являются частью синтаксиса JavaScript. Они выполняют разные функции, хотя могут быть похожи в некоторых случаях. Давайте рассмотрим их отличия.
Оператор rest (... )
СкопированоRest-оператор используется для сбора оставшихся аргументов функции в массив.
function sum(...args) { return args.reduce((total, num) => total + num, 0)}console.log(sum(1, 2, 3, 4))// 10
function sum(...args) {
return args.reduce((total, num) => total + num, 0)
}
console.log(sum(1, 2, 3, 4))
// 10
Таким образом можно обрабатывать неизвестное количество аргументов, переданных в функцию.
Оператор spread (... )
СкопированоSpread-оператор используется для распространения элементов массива или свойств объекта.
const arr1 = [1, 2, 3]const arr2 = [4, 5, 6]const combinedArray = [...arr1, ...arr2]console.log(combinedArray)// [1, 2, 3, 4, 5, 6]
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
const combinedArray = [...arr1, ...arr2]
console.log(combinedArray)
// [1, 2, 3, 4, 5, 6]
Оператор spread также используется для создания поверхностных копий массивов или объектов.
const originalArray = [1, 2, 3]const copiedArray = [...originalArray]console.log(copiedArray)// [1, 2, 3]
const originalArray = [1, 2, 3]
const copiedArray = [...originalArray]
console.log(copiedArray)
// [1, 2, 3]
Таким образом, основное отличие между rest- и spread-операторами заключается в их применении. Rest используется для сбора аргументов в функции, тогда как spread — для распространения элементов массивов или объектов.
отвечает
СкопированоОператоры spread и rest выглядят одинаково, как три точки — ., но выполняют противоположные действия.
Что делает оператор rest?
СкопированоСобирает оставшиеся аргументы функции в массив. Этот синтаксис используется при объявлении функции.
function doSomething(first, second, ...array) { console.log(first, second, array)}doSomething(1, 2, 3, 4, 5)// 1 2 [3, 4, 5]
function doSomething(first, second, ...array) {
console.log(first, second, array)
}
doSomething(1, 2, 3, 4, 5)
// 1 2 [3, 4, 5]
Собирает оставшиеся элементы массива в новый массив. Используется при деструктуризации массива.
const [first, second, ...array] = [1, 2, 3, 4, 5]console.log(first, second, array)// 1 2 [3, 4, 5]
const [first, second, ...array] = [1, 2, 3, 4, 5]
console.log(first, second, array)
// 1 2 [3, 4, 5]
Собирает оставшиеся свойства объекта в новый объект. Используется при деструктуризации объекта.
const { c, ...object } = { a: 1, b: 2, c: 3 }console.log(c, object)// 3 {a: 1, b: 2}
const { c, ...object } = { a: 1, b: 2, c: 3 }
console.log(c, object)
// 3 {a: 1, b: 2}
⛔ Оператор rest собирает все оставшиеся элементы, свойства или аргументы функции, если написать что-то после них, это вызовет ошибку:
const [first, second, ...array, five] = [1, 2, 3, 4, 5]// five после ...array// Ошибка!
const [first, second, ...array, five] = [1, 2, 3, 4, 5]
// five после ...array
// Ошибка!
Что делает оператор spread?
СкопированоРаскладывает массив на отдельные аргументы при вызове функции.
function doSomething(first, second, third) { console.log(first, second, third)}const array = [1, 2, 3]doSomething(...array)// 1 2 3
function doSomething(first, second, third) {
console.log(first, second, third)
}
const array = [1, 2, 3]
doSomething(...array)
// 1 2 3
Раскладывает массив на отдельные элементы. Этот синтаксис используется при создании массива с помощью литерала [.
const array = [3, 4]const newArray = [1, 2, ...array, 5]console.log(newArray)// [1, 2, 3, 4, 5]
const array = [3, 4]
const newArray = [1, 2, ...array, 5]
console.log(newArray)
// [1, 2, 3, 4, 5]
Раскладывает объект на отдельные свойства. Этот синтаксис используется при создании объекта с помощью литерала {}.
const object = { b: 2, c: 3 }const newObject = { a: 1, ...object }console.log(newObject)// { a: 1, b: 2, c: 3}
const object = { b: 2, c: 3 }
const newObject = { a: 1, ...object }
console.log(newObject)
// { a: 1, b: 2, c: 3}
Оператор spread может стоять где угодно и использоваться любое количество раз в рамках одного вызова функции или создания массива, объекта.
Так тоже можно:
const firstArray = [3, 4]const secondArray = [15, 16]const newArray = [1, 2, ...firstArray, 5, ...secondArray]console.log(newArray)// [1, 2, 3, 4, 5, 15, 16]
const firstArray = [3, 4]
const secondArray = [15, 16]
const newArray = [1, 2, ...firstArray, 5, ...secondArray]
console.log(newArray)
// [1, 2, 3, 4, 5, 15, 16]