ES6 ввел много новых функций в JavaScript, в том числе оператор распространения (...)
, который расширяет итерабильный объект в список его отдельных элементов.
Если это еще не ясно, не волнуйтесь, мы будем вдаваться в подробности в следующих разделах, когда мы действительно научимся использовать его в реальных сценариях.
Копировать массивы или объекты
Посмотрите на следующий скрипт, можете ли вы сказать, какой вывод?
const listA = [1, 2, 3] const listB = listA listB.push(4) console.log('listA:', listA) console.log('listB:', listB)
Вывод для этого примера – следующее:
"listA:" [1, 2, 3, 4] "listB:" [1, 2, 3, 4]
Ждать! какие? Почему Lista
Изменил его значение, когда мы явно изменили ListB
Анкет Ну, причина проста, когда мы выполнили задание:
const listB = listA
JavaScript назначен ListB
Ссылка на списка
, Так по сути Lista
и ListB
указывают на тот же список в памяти.
Итак, как мне создать копию? Вот где операторы распространения входят в картинку. Давайте снова посмотрим на тот же пример, используя операторы спреда:
const listC = [1, 2, 3] const listD = [...listC] listD.push(4) console.log('listC:', listC) console.log('listD:', listD)
И вывод:
"listC:" [1, 2, 3] "listD:" [1, 2, 3, 4]
В этом случае, используя оператор спреда, мы делаем новую копию в памяти массива, поэтому, когда мы обновляем Listd
Мы ни в коем случае не влияем Listc
Анкет
Увидеть это сами в действии:
Точно так же мы можем использовать эту технику для копирования объектов, однако есть улов:
const article = { title: 'How to Use the Spread Operator (...) in JavaScript', claps: 1000000, author: { name: 'Juan', publication: 'LiveCodeStream' } } const articleCopy = { ...article } articleCopy.title = 'Strange behaviours with spread operator and deep copy'; articleCopy.author.name = 'JC'; console.log('Original title:', article.title); console.log('Original author:', article.author.name) console.log('Copy title:', articleCopy.title) console.log('Copy author:', articleCopy.author.name)
Прежде чем объяснить, что здесь происходит, давайте посмотрим на вывод:
Original title: How to Use the Spread Operator (...) in JavaScript Original author: JC Copy title: Strange behaviours with spread operator and deep copy Copy author: JC
Опять что?! Теперь, когда мы использовали оператор спреда, мы получили копию в память о исходном объекте, однако некоторые свойства скопировали в значениях, а некоторые в качестве ссылки, как в случае с автором (обратите внимание на то, как изменился заголовок только для копии, но автор
был изменен как оригиналом, так и копией).
Здесь произошло то, что оператор спреда не сделает глубокую копию, но он займет каждый из элементов в исходном объекте/списке и сопоставил бы их на новую позицию в памяти. Однако, если один из элементов оказался ссылкой на другой объект, он просто сделает копию ссылки в память, но это не изменит то, на что он ссылается.
Есть способы сделать глубокую копию, используя оператор спреда, но мы не будем смотреть на них в этом посте, однако, если вы любопытны, но ленивы, чтобы Google, это Статья От доктора Дерека Остина подробно объясняет это.
Кодепен:
Объединение массивов или объектов
Оператор спреда очень полезен для копирования объектов, но мы также можем использовать его для объединения нескольких объектов или списков в один объект.
Давайте посмотрим на пример слияния списков и одного объединения объектов:
const list1 = [1, 2, 3] const list2 = [4, 5] const mergedList = [...list1, ...list2] console.log('Merged List: ', mergedList) const obj1 = {a: 1, b: 2} const obj2 = {c: 3} const mergedObj = {...obj1, ...obj2} console.log('Merged Object: ', mergedObj)
Это работает, как и ожидалось, следуя соображениям сверху. Вот выход:
Merged List: [1,2,3,4,5] Merged Object: {"a":1,"b":2,"c":3}
Тем не менее, с JavaScript все может стать немного странным:
const weird1 = {...obj1, ...list2} console.log('Merged list as object', weird1)
В этом случае мы объединяем наши obj1
и List2
в объект, знаете ли вы результат?
Merged list as object {"0":4,"1":5,"a":1,"b":2}
Это удивительно сработало! Это выглядит немного странно, но вы можете легко предсказать, каким будет результат.
Будет ли это также сработать наоборот? Объединение объекта в список?
const weird2 = [...obj1, ...list1] console.log('Merged list as object', weird2)
Есть предположение?
object is not iterable (cannot read property Symbol(Symbol.iterator))
Может быть, не то, что вы ожидали, но невозможно объединить объект или для этого случая скопировать объект в список. Причина в том, что вы не можете повторить объект. Если вы реализуете объект как итерабильный, то это можно было бы сделать.
Кодепен:
Проходящие аргументы
Вы когда -нибудь пытались найти максимальное (или минимальное) значение в массиве? Ваш первый ответ на этот вопрос, вероятно, состоит в том, чтобы использовать Math.max
Функция, однако, это не сработает, нам нужно сделать что -то еще. Почему?
Math.max
Как другие подобные функции, по определению ожидают несколько параметров, посмотрите на определение на Mdn Анкет Если мы попытаемся передать массив в качестве одного значения, это значение не будет таким числом, как ожидаемое, и функция вернется НАН
Анкет Чтобы исправить это, мы можем использовать оператор спреда, чтобы преобразовать массив в список аргументов следующим образом:
console.log('Math.max(1, 2, 3)', Math.max(1, 2, 3)) console.log('Math.max([1, 2, 3])', Math.max([1, 2, 3])) console.log('Math.max(...[1, 2, 3])', Math.max(...[1, 2, 3]))
И вывод:
Math.max(1, 2, 3) 3 Math.max([1, 2, 3]) null Math.max(...[1, 2, 3]) 3
Ницца! Но как я могу создать такую функцию сам? Давайте посмотрим на пример:
function test(param1, ...args) { console.log(' -> param1', param1) console.log(' -> args', args) } console.log('test(1):') test(1) console.log('test(1, "a", "b", "c"):') test(1, 'a', 'b', 'c')
И вывод:
test(1): -> param1 1 -> args [] test(1, "a", "b", "c"): -> param1 1 -> args ["a","b","c"]
Использование распространения как часть функции объявления – отличный способ преобразовать аргументы в массив. Подробнее по этой теме дальше.
Кодепен:
Разрушение массивов или объектов
Мы видели, как копировать и объединять объекты, но … Можем ли мы «смягчить» объекты? Это называется разрушением … и да! Давайте взглянем:
console.log('first', first) console.log('second', second) console.log('rest', rest)
выход:
first 1 second 2 rest [3,4,5]
Аналогично, мы можем сделать то же самое с объектами:
const article = { title: 'Cool article', claps: 10000000, author: { name: 'Juan' } } const { title, claps, author: { name }} = article console.log('title', title) console.log('claps', claps) console.log('author name', name)
Выход:
title Cool article claps 10000000 author name Juan
С объектами происходит что -то интересное, мы можем даже получить вложенные свойства. Этот метод широко используется в компонентах React и при использовании Redux или аналогичного.
Теперь, когда мы понимаем эту функцию, у вас, вероятно, есть лучшее представление о том, что произошло именно в предыдущем примере объявления функции.
Кодепен:
Nodelist к массиву
Проще говоря, мы можем сделать что -то вроде:
[...document.querySelectorAll('div')]
Преобразовать строку в символы
Строка является итерабильной, и мы можем использовать их, чтобы расширить их в качестве списка символов следующим образом:
const name = 'Juan' const chars = [...name];
Удалить дубликаты
Можем ли мы использовать операторы спреда, чтобы получить только уникальные значения? Да, но не напрямую … нам нужно использовать что -то еще в сочетании с оператором спреда, Наборы Анкет
const list = [1, 3, 1, 3, 3, 2] const uniqueList = [...new Set(list)]
Значение для Университет
сейчас:
[1, 3, 2]
Вывод
Оператор спреда (…) очень полезен для работы с массивами и объектами в JavaScript. Вы увидите их много при работе с такими рамками, как React, и при разработке редукторов. Это определенно важная функция для изучения и освоения, если вы работаете с JavaScript.
Если вы хотите узнать больше об ES6, проверьте мой пост: когда не использовать функции стрелки JavaScript
Спасибо за чтение!
Оригинал: “https://dev.to/livecodestream/how-to-use-the-spread-operator-in-javascript-35bn”