Вступление
Если вы хотите выбрать элементы из массива или объекта до обновления ES2015 до JavaScript, вам придется выбирать их индивидуально или использовать цикл.
Спецификация ES2015 представила назначение деструктуризации , более быстрый способ извлечения элементов массива или свойств объекта в переменные.
В этой статье мы будем использовать назначение деструктуризации для получения значений из массивов и объектов в переменные. Затем мы увидим расширенное использование деструктурирующего присваивания, которое позволяет нам устанавливать значения по умолчанию для переменных, захватывать неназначенные записи и менять местами переменные в одной строке.
Разрушение массива
Когда мы хотим взять элементы из массива и использовать их в отдельных переменных, мы обычно пишем такой код:
let myArray = [1, 2, 3];
let first = myArray[0];
let second = myArray[1];
let third = myArray[2];
После крупного обновления JavaScript ES2015 теперь мы можем выполнять ту же задачу следующим образом:
let myArray = [1, 2, 3];
let [first, second, third] = myArray;
Во втором, более коротком примере использовался синтаксис
деструктуризации JavaScript для myArray
. Когда мы деструктурируем
массив, мы копируем значения его элементов в переменные. Синтаксис
деструктуризации массива аналогичен синтаксису обычного назначения
переменных ( let x = y;
). Разница в том, что левая часть состоит из
одной или нескольких переменных в массиве .
Приведенный выше код создал три новые переменные: first
, second
и
third
. Он также присвоил значения этим переменным: first
равна 1,
second
равна 2, а third
равна 3.
С этим синтаксисом JavaScript видит, что first
и 1 имеют одинаковый
индекс в своих соответствующих массивах, 0. Переменным присваиваются
значения, соответствующие их порядку. Пока местоположение совпадает
между левой и правой стороной, назначение деструктуризации будет
выполнено соответственно.
Синтаксис деструктуризации также работает с объектами, давайте посмотрим, как это сделать.
Разрушение объекта
До появления синтаксиса деструктуризации, если бы мы хотели сохранить свойства объекта в разных переменных, мы бы написали такой код:
const foobar = {
foo: "hello",
bar: "world"
};
const foo = foobar.foo;
const bar = foobar.bar;
Благодаря синтаксису деструктуризации мы теперь можем быстро сделать то же самое с меньшим количеством строк кода:
const foobar = {
foo: "hello",
bar: "world"
};
const { foo, bar } = foobar;
В то время как элементы массива деструктурируются по их положению,
свойства объектов деструктурируются по их ключевым именам. В приведенном
выше примере после объявления объекта foobar
мы создаем две
переменные: foo
и bar
. Каждой переменной присваивается значение
одноименного свойства объекта. Следовательно, foo
- это «привет», а
bar
- «мир».
Примечание . Назначение деструктуризации работает независимо от
того, объявляете ли вы переменную с помощью var
, let
или const
.
Если вы предпочитаете давать другое имя переменной при деструктуризации объекта, мы можем внести небольшие изменения в наш код:
const foobar = {
foo: "hello",
bar: "world"
};
const { foo: baz, bar } = foobar;
console.log(baz, bar); // hello world
С помощью двоеточия мы можем сопоставить свойство объекта и дать
созданной переменной новое имя. Приведенный выше код не создает
переменную foo
. Если вы попытаетесь использовать foo
вы получите
ReferenceError
, указывающую, что он не был определен.
Теперь, когда у нас есть основы деструктуризации массивов и объектов, давайте рассмотрим некоторые хитрости с этим новым синтаксисом. Мы начнем с нашего варианта выбора значений по умолчанию.
Значения по умолчанию в деструктурированных переменных
Что произойдет, если мы попытаемся деструктурировать больше переменных, чем количество элементов массива или свойств объекта? Давайте посмотрим на небольшом примере:
let [alpha1, alpha2, alpha3] = ['a', 'b'];
console.log(alpha1, alpha2, alpha3);
Наш вывод будет:
ab undefined
Неназначенным переменным устанавливается значение undefined
. Если мы
хотим, чтобы наши деструктурированные переменные не были undefined
,
мы можем дать им значение по умолчанию . Давайте повторно
воспользуемся предыдущим примером и alpha3
по умолчанию на 'c':
let [alpha1, alpha2, alpha3 = 'c'] = ['a', 'b'];
console.log(alpha1, alpha2, alpha3);
Если мы запустим это в node
или в браузере, мы увидим в консоли
следующий вывод:
abc
Значения по умолчанию создаются с помощью =
при создании переменной.
Когда мы создаем переменные со значением по умолчанию, если в среде
деструктуризации есть совпадение, оно будет перезаписано.
Давайте подтвердим, что это так, на следующем примере, который устанавливает значение по умолчанию для объекта:
const { prime1 = 1, prime2 } = { prime1: 2, prime2: 3 };
console.log(prime1, prime2);
В приведенном выше примере по умолчанию для prime1
значение 1. Оно
должно быть заменено на 2, поскольку в правой части присваивания
prime1
Запуск этого дает:
2 3
Большой! Мы подтвердили, что значения по умолчанию перезаписываются при совпадении. Это также хорошо, потому что первое простое число действительно равно 2, а не 1.
Значения по умолчанию полезны, когда у нас слишком мало значений в массиве или объекте. Давайте посмотрим, как обрабатывать случаи, когда есть намного больше значений, которые не обязательно должны быть переменными.
Захват неназначенных записей в деструктурированном назначении
Иногда нам нужно выбрать несколько записей из массива или объекта и
зафиксировать оставшиеся значения, которые мы не поместили в отдельные
переменные. Мы можем сделать это с помощью оператора ...
Поместим первый элемент массива в новую переменную, но оставим остальные элементы в новом массиве:
const [favoriteSnack, ...fruits] = ['chocolate', 'apple', 'banana', 'mango'];
В приведенном выше коде мы устанавливаем favoriteSnack
на «шоколад».
Поскольку мы использовали оператор ...
fruits
равны оставшимся
элементам массива, а именно ['apple', 'banana', 'mango']
.
Мы называем переменные, созданные с помощью ...
в деструктурирующем
назначении, остальным элементом . Остальной элемент должен быть
последним элементом назначения деструктуризации.
Как вы могли догадаться, мы также можем использовать остальные элементы в объектах:
const { id, ...person } = {
name: 'Tracy',
age: 24,
id: 1020212,
};
Мы извлекаем id
объекта в правой части деструктурирующего присваивания
в его собственную переменную. Затем мы помещаем оставшиеся свойства
объекта в переменную person
В этом случае id
будет равен 1020212
а
person
будет равен { name: 'Tracy', age: 24 }
.
Теперь, когда мы увидели, как сохранить все данные, давайте посмотрим, насколько гибким является назначение деструктуризации, когда мы хотим опустить данные.
Избирательные значения в деструктурирующем назначении
Нам не нужно назначать каждую запись переменной. Например, если мы хотим назначить только одну переменную из многих параметров, мы можем написать:
const [name] = ['Katrin', 'Judy', 'Eva'];
const { nyc: city } = { nyc: 'New York City', ldn: 'London' };
Мы присвоили name
«Катрин» из массива и city
«Нью-Йорк» из объекта.
С объектами, поскольку мы сопоставляем их по именам ключей, легко
выбрать конкретные свойства, которые мы хотим использовать в переменных.
В приведенном выше примере, как мы могли захватить «Катрин» и «Еву», не
снимая также и «Джуди»?
Синтаксис деструктуризации позволяет нам вставлять дыры для значений, которые нам не интересны. Давайте воспользуемся дырой, чтобы захватить "Катрин" и "Еву" за один раз:
const [name1, , name2] = ['Katrin', 'Judy', 'Eva'];
Обратите внимание на разрыв в присвоении переменных между name1
и
name2
.
До сих пор мы видели, насколько гибким может быть назначение деструктуризации, хотя и только с фиксированными значениями. В JavaScript массивы могут содержать массивы, а объекты могут быть вложены в объекты. У нас также могут быть массивы с объектами и объекты с массивами. Давайте посмотрим, как деструктурирующее назначение обрабатывает вложенные значения.
Разрушение вложенных значений
Мы можем вкладывать деструктурирующие переменные в соответствие вложенным записям массива и объекта, что дает нам детальный контроль над тем, что мы выбираем. Подумайте о наличии массива массивов. Давайте скопируем первый элемент каждого внутреннего массива в их собственную переменную:
let [[part1], [part2], [part3], [part4]] = [['fee', 'mee'], ['fi', 'li'], ['fo', 'ko'], ['fum', 'plum']];
console.log(part1, part2, part3, part4);
Запуск этого кода отобразит следующий вывод:
fee fi fo fum
Просто заключив каждую переменную в левой части с помощью []
,
JavaScript знает, что нам нужно значение в массиве, а не сам массив.
Когда мы деструктурируем вложенные объекты, мы должны сопоставить ключ вложенного объекта, чтобы получить его. Например, давайте попробуем зафиксировать некоторые детали заключенного в JavaScript:
const {
name,
crimes: {
yearsToServe
}
} = {
name: 'John Doe',
crimes: {
charged: ['grand theft auto', 'stealing candy from a baby'],
yearsToServe: 25
}
};
console.log(yearsToServe);
Чтобы получить yearsToServe
, нам сначала нужно сопоставить вложенный
объект crimes
В этом случае в правой части для свойства yearsToServe
crimes
установлено значение 25. Следовательно, нашей yearsToServe
будет присвоено значение 25.
Обратите внимание, что в приведенном выше примере crimes
Мы создали
две переменные: name
и yearsToServe
. Несмотря на то, что мы должны
соответствовать вложенной структуре, JavaScript не создает промежуточных
объектов.
Пока что вы отлично справились с описанием многих возможностей деструктурированного синтаксиса. Давайте посмотрим на его практическое использование!
Примеры использования для деструктуризации массивов и объектов
Есть много применений для деструктуризации массивов и объектов, помимо преимуществ кода. Вот пара распространенных случаев, когда деструктуризация улучшает читаемость нашего кода:
Для петель
Разработчики используют назначение деструктуризации, чтобы быстро
извлечь интересующие значения из элемента в цикле for
Например, если
вы хотите распечатать все ключи и значения объекта, вы можете написать
следующее:
const greetings = { en: 'hi', es: 'hola', fr: 'bonjour' };
for (const [key, value] of Object.entries(greetings)) {
console.log(`${key}: ${value}`);
}
Сначала мы создаем greetings
которой хранится, как сказать «привет» на
разных языках. Затем мы перебираем значения объекта, используя метод
Object.entries()
который создает вложенный массив. Каждое свойство
объекта представлено двумерным массивом, в котором первый элемент
является ключом, а второй - его значением. В этом случае
Object.entries()
создает следующий массив
[['en', 'hi'], ['es', 'hola'], ['fr', 'bonjour']]
.
В нашем for
мы деструктурируем отдельные массивы на key
и value
переменных. Затем мы записываем их в консоль. Выполнение этой программы
дает следующий результат:
en: hi
es: hola
fr: bonjour
Обмен переменными
Мы можем использовать синтаксис деструктуризации, чтобы поменять местами переменные без временной переменной. Допустим, вы на работе и делаете перерыв. Вы хотели чаю, а ваш коллега хотел кофе. К сожалению, напитки перепутались. Если бы это было в JavaScript, вы можете легко поменять местами напитки, используя синтаксис деструктуризации:
let myCup = 'coffee';
let coworkerCup = 'tea';
[myCup, coworkerCup] = [coworkerCup, myCup];
Теперь в myCup
есть «чай», а в coworkerCup
- «кофе». Обратите
внимание, как мы не использовали let
, const
или var
при
использовании деструктурирующего присваивания. Поскольку мы не объявляем
новые переменные, нам нужно опустить эти ключевые слова.
Заключение
С помощью деструктурирующего назначения мы можем быстро извлекать значения из массивов или объектов и помещать их в их собственные переменные. JavaScript делает это, сопоставляя позицию в массиве переменной или имя переменной с именем свойства объекта.
Мы видели, что мы можем присвоить значения по умолчанию создаваемым
переменным. Мы также можем захватить оставшиеся свойства массивов и
объектов с помощью оператора ...
Мы можем пропускать записи, имея
дыры, которые обозначены запятыми, между которыми ничего нет. Этот
синтаксис также достаточно гибкий, чтобы деструктурировать вложенные
массивы и объекты.
Мы предоставили пару отличных мест для использования задания деструктуризации. Где вы будете их использовать в следующий раз?