Зарегистрируйтесь, чтобы продолжить обучение

Дестракчеринг JS: Коллекции

В функциональных языках очень популярна техника Destructuring assignment. Она слабо представлена в императивных языках, а в JavaScript вообще отсутствовала. Но после появления ES6-стандарта возможности в JavaScript по Destructuring assignment стали мощными и сравнялись с функциональными языками.

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

Определение Destructuring assignment

Синтаксис деструктивного присваивания в JavaScript похож на синтаксис создания массива или объекта. При этом это разные операции.

Разберем, как обычно решаются типичные задачи в коде. Например, у нас есть массив из двух элементов. Мы хотим каждый из них присвоить своей переменой, чтобы независимо работать с ними:

const animals = ['Dog Name', 'Cat Name']

const myDog = animals[0]
const myCat = animals[1]

Показанный здесь подход является предпочтительным. Но это можно сделать еще проще, если использовать разрешающие присваивания или просто Destructuring. Делается это так:

const animals = ['Dog Name', 'Cat Name']

const [myDog, myCat] = animals

Слева от составного объекта, который мы хотим разложить, описывается структура. Она соответствует правой части. В ней вместо конкретных значений подставляем идентификаторы. В примере это константы myDog и myCat.

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

Как видим, Destructuring assignment помогает сократить код и сделать его более понятным. При этом индексы здесь уже не участвуют.

Rest

Мы можем использовать rest-оператор:

const x = [1, 2, 3, 4, 5]
const [y, z] = x
console.log(y) // 1
console.log(z) // 2

В итоге в y попадает первый элемент, в z — второй элемент. Остальные элементы остаются в исходном массиве и не задействованы в присваивании. Но это можно поменять и использовать rest-operator — операцию rest. Она соберет все оставшиеся элементы в массив, который мы потом можем воспользоваться:

const x = [1, 2, 3, 4, 5]
const [y, z, ...rest] = [1, 2, 3, 4, 5]
console.log(y) // 1
console.log(z) // 2
console.log(rest) // [3, 4, 5]

Rest может использоваться не только в определении функций, но и в Destructuring. При этом он используется в самом конце, и его нельзя поставить в середине. Такой же механизм работает и с объектами.

Объекты

Рассмотрим пример, как раскладывается объект:

const { a, b } = { a: 1, b: 2 }
console.log(a) // 1
console.log(b) // 2

Слева мы указываем только идентификаторы, которые должны совпадать с именем ключа в правой части. Туда записывается соответствующее значение по ключу с таким же именем.

Значения по умолчанию

Еще Destructuring assignment позволяет указывать значения по умолчанию. Например:

const [a = 5, b = 7] = [1]
console.log(a) // 1
console.log(b) // 7

В левой части у нас два элемента, в правой части — один элемент. При присваивании ошибки не происходят. В a записывается единица, а в b записывается семь, потому что это значение по умолчанию.

Обмен переменных местами

Рассмотрим пример, который есть почти во всех языках — это обмен переменных местами без использования третьей переменной. В JavaScript это делается так:

let a = 1
let b = 3;

[a, b] = [b, a]
console.log(a) // 3
console.log(b) // 1

Возврат функций

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

const f = () => [1, 2]

const [a, b] = f()
console.log(a) // 1
console.log(b) // 2

Это не отличается от просто использования массива. Это означает, что Destructuring assignment работает независимо от того, откуда идут данные. Получается, нам неважен источник этих данных. Это просто использование литерала. Главное, что мы слева, описав его структуру, можем разложить его на составляющие.

Это важно, так как открывает много возможностей в использовании Destructuring assignment в разных местах программы. Например, в определении функций.

Определение функций

Допустим, у нас есть массив животных — cat и dog:

const animals = [
  { age: 5, type: 'cat' },
  { age: 10, type: 'dog' },
]
const result = animals.filter(({ age }) => age > 7)

// [ { age: 10, type: 'dog' } ]
console.log(result)

Здесь мы как раз делаем Destructuring assignment. Вместо того, чтобы записывать объект и обращаться к его свойству age, мы напрямую в параметрах функции делаем разложение объекта. Получается, мы извлекаем age сразу из объекта, а остальную часть игнорируем.

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

Составной объект

Еще Destructuring assignment в JavaScript позволяет раскладывать составные объекты, что делает его мощным механизмом. Рассмотрим пример:

const metadata = {
  title: 'Scratchpad',
  translations: [
    { locale: 'de', title: 'JavaScript-Umgebung' },
  ],
  url: '/en-US/docs/Tools/Scratchpad',
}

Здесь у нас есть metadata — составной объект, который внутри содержит массив. А этот массив содержит объекты. И с помощью Destructuring assignment мы можем его разложить на элементы:

const {
  title: englishTitle,
  translations: [{ title: localeTitle }],
} = metadata

console.log(englishTitle) // "Scratchpad"
console.log(localeTitle) // "JavaScript-Umgebung"

Здесь мы слева описываем структуру, в которой говорим, что title — это englishTitle. Получается, мы делаем переименование — говорим, что по ключу title значение нужно записать в переменную с именем englishTitle. В нашем случае это константа.

Также мы раскладываем translations и описываем, что происходит внутри. В итоге внутренний title мы записываем в localTitle.

Получается, что мы описали структуру, подобную верхней, и переименовали title, чтобы они не пересекались. Далее мы их распечатаем, и в итоге появляются соответствующие значения из исходного составного объекта.

Выводы

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

Плюсов у Destructuring assignment много: код становится чище, меньше и компактнее. При этом в отличие от других подходов, которые позволяют писать более компактный код, Destructuring assignment еще и улучшает его читаемость.

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


Дополнительные материалы

  1. Официальная документация

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff