Понимание синтаксиса деструктуризации в JavaScript
Перевод: Marina Mosti — Understanding the JavaScript Destructuring Syntax
Деструктуризация обеспечивает простой, но эффективный способ создания переменных из частей массива или свойств объекта — этот подход обычно позволяет получить лучший и более понятный код.
В JavaScript (и других языках программирования) мы часто работаем с группами данных, такими как массив и объект. Доступ к этим данным обычно осуществляется с помощью индекса для массивов и свойства для объектов, но приходилось ли вам когда-нибудь обращаться к одному и тому же определенному фрагменту данных снова и снова в коде до точки, из-за чего код становилось все труднее и труднее понимать?
Ясность кода жизненно важна при работе с командами и для будущего вашей работы. Взгляните на следующие фрагменты кода.
//--- Base example if (users[0].capabilities[0].type === 'edit' && users[0].active) //--- By hand const user = users[0] const active = user.active const canEdit = user.capabilities[0].type if (canEdit === 'edit' && active) //--- With destructuring const [{ active, capabilities: [{ type: canEdit }] }] = users if (canEdit === 'edit' && active)
Несмотря на то, что второй пример намного яснее и, вероятно, будет легче расшифровать любому члену команды, последний пример создается с помощью вложенной деструктуризации как объекта, так и вложенного массива, и это то, что мы рассмотрим сегодня. Так как хорошо разбираться с синтаксисом деструктуризации очень важно особенно при чтение чужого кода.
Disclaimer: эта статья предназначена для людей, которые впервые изучают синтаксис деструктурированого присваивания и испытывают трудности с его пониманием. Я расскажу только о возможностях, которые дает нам эта функция. Для получения более подробных примеров и информации я рекомендую прочитать примеры на страницы MDN Destructuring.
Начнем с массивов
const people = ['Karen', 'Bob']` sendItem(people[0], 'chocs')` sendItem(people[1], 'coal')`
На первый взгляд, приведенный выше код довольно ясен. По какой-то причине тот, кто находится в индексе 0, кажется, получает хороший предмет chocs, в то время как человек с индексом 1 получает только кусок угля coal.
Может быть, мы могли бы переписать код, чтобы он был немного понятнее.
const people = ['Karen', 'Bob'] const bestFriend = people[0] const archEnemy = people[1] sendItem(bestFriend, 'chocs') sendItem(archEnemy, 'coal')
Теперь, когда мы объявили некоторые переменные, которые более точно описывают, что означают индексы 0 и 1, код становится легче читать и понимать. Однако вы можете заметить некоторую многословность в том месте, где мы объявляем обе константы.
Сейчас это не имеет большого значения, поскольку нам нужно извлечь из массива только двух человек. Но что, если их было бы 5 или 10? Из-за этой необходимости синтаксис деструктуризации сделал нашу жизнь лучше в ES6.
Давайте подойдем к предыдущему примеру, используя этот синтаксис.
const people = ['Karen', 'Bob'] const [bestFriend, archEnemy] = people sendItem(bestFriend, 'chocs') sendItem(archEnemy, 'coal')
Поначалу этот синтаксис может быть очень пугающим, но вспомните времена старшей школы, когда вы изучали алгебру, и как у вас могло быть две стороны уравнений.
Вы уже знаете, как объявлять массив, поэтому, если я вам скажу:
const people = [bestFriend, archEnemy]
В этом есть смысл, правда? Переменной слева присваивается содержимое справа.
Если мы инвертируем предыдущий оператор, мы получим:
[bestFriend, archEnemy] = const people
Надеюсь, в это время вы начинаете получать тот момент озарения. Если мы посмотрим на предыдущий пример, одно сразу покажется неуместным. Мы точно знаем, что в JavaScript мы не можем установить ключевое слово const для объявления переменной справа от присваивания. Кроме того, у нас уже есть массив людей, объявленный вверху, поэтому мы действительно не хотим объявлять его повторно, а хотим извлечь его содержимое в две новые переменные.
Таким образом, мы перемещаем ключевое слово const в начало, и получаем следующее:
const [bestFriend, archEnemy] = people
Это означает: я хочу создать две переменные, bestFriend и archEnemy, из массива people. Первая переменная, bestFriend, будет фиксировать значение в индексе 0 массива people; а вторая переменная, archEnemy, будет фиксировать значение внутри индекса 1.
Если вам интересно, откуда языку известно, что мы имеем в виду индексы 0 и 1, то это из-за позиции, которую они занимают в синтаксисе массива в левой части присваивания.
// index 0 index 1 const [bestFriend, archEnemy] = people
Работа с объектами
Итак, деструктуризация при работе с массивами — это хорошо, но это не обычный сценарий. Большую часть времени (по крайней мере, таков мой опыт) я использую деструктурирование при работе с объектами.
Давайте создадим объект «человек», над которым мы можем работать в качестве нашего примера.
const bestFriend = { name: 'Karen', age: 35, species: 'Reptilian', alignment: 'Chaotic neutral', favorites: [ { type: 'food', value: 'ice cream' }, { type: 'animal', value: 'otter' } ] } const archEnemy = { age: 40, name: 'Unavailable' }
При деструктуризации объекта у вас есть возможность легко создать переменную для каждого свойства, к которому вы хотите получить доступ. Таким образом, мы можем обойтись следующим:
const { age, favorites, name } = bestFriend console.log(age) // 35 console.log(favorites[0].value) // ice cream console.log(name) // Karen
Если вы хотите дать переменной собственное имя вместо имени свойства, вы можете легко сделать это следующим образом:
const { age: howOld, name: howToCall } = bestFriend console.log(howOld) // 35 console.log(howToCall) // Karen
Теперь, когда вы обычно работаете с объектом и хотите получить доступ к одному из его свойств, вы должны сделать это, как в следующем примере.
sendItem(bestFriend, bestFriend.favorites[0].value, bestFriend.age) sendItem(archEnemy, 'coal', archEnemy.age)
На первый взгляд, не зная внутреннего API функции sendItem, это не очень понятно. Мы могли бы использовать простые переменные, чтобы прояснить наши намерения. Мы хотим послать нашему другу столько подарков, сколько его возраст (age), и столько врагу сколько его возраст.
const perfectGift = bestFriend.favorites[0].value const amountOfGiftsForFriend = bestFriend.age const amountOfCoalForEnemy = archEnemy.age sendItem(bestFriend, perfectGift, amountOfGiftsForFriend) sendItem(archEnemy, 'coal', amountOfCoalForEnemy)
Просто сделав эти простые изменения, вы уже можете увидеть, что читаемость кода резко улучшается. Теперь давайте рассмотрим тот же пример с деструктуризацией.
const {age: amountOfGiftsForFriend, favorites: [{ value: perfectGift }]} = bestFriend const {age: amountOfCoalForEnemy} = archEnemy sendItem(bestFriend, perfectGift, amountOfGiftsForFriend) sendItem(archEnemy, 'coal', amountOfCoalForEnemy)
Давайте деструктурируем (😄) этот пример, чтобы лучше понять, что происходит.
В первой строке мы деструктурируем несколько свойств из объекта bestFriend. Нам нужно знать два фрагмента данных: perfectGift, который должен быть значением первого элемента в массиве favorites, и amountOfGiftsForFriend, который должен быть равен age.
Поскольку мы хотим переименовать свойство age нашего объекта в amountOfGiftsForFriend, чтобы сделать его более читабельным, мы должны использовать синтаксис, который позволяет нам переименовать это свойство в другую переменную. Итак, сначала мы деструктурируем возраст следующим образом:
const { age: amountOfGiftsForFriend } = bestFriend console.log(amountOfGiftsForFriend) // 35
Затем нам нужно деструктурировать свойство favorites.
const { favorites } = bestFriend console.log(favorites) // [ // { type: 'food', value: 'ice cream' }, // { type: 'animal', value: 'otter' } // ]
А теперь оставайтесь со мной, favorites — это массив, верно? А в первой части этой статьи мы узнали, что можно деструктурировать массивы по их индексу. Помните?
Поэтому, если нам нужно получить доступ к первому объекту в массиве с индексом 0, мы можем выполнить деструктуризацию массива, вложенного в ту же строку.
const { favorites: [firstFavorite] } console.log(firstFavorite) // { type: 'food', value: 'ice cream' }
Теперь нам просто нужно указать синтаксису деструктуризации, какое свойство этого первого объекта нам нужно и как мы хотим его переименовать.
const { favorites: [{ value: perfectGift }] } console.log(perfectGift) // ice cream
Вот codesandbox с примером на тот случай, если вы захотите проверить его самостоятельно.
Заключение
Как я упоминал в начале статьи, это небольшое объяснение предназначено только для того, чтобы вы миновали тот момент OMG WHAT IS DIS, когда вы впервые сталкиваетесь с синтаксисом где-то в «дикой» природе.
Я лично считаю, что деструктуризация может внести большую ясность в код, и это фантастический инструмент, который стоит иметь за плечами разработчика. Тем не менее, я рекомендую вам хотя бы быстро прочитать примеры, предоставленные MDN, чтобы глубже понять возможности, которые может дать вам этот синтаксис.
Как всегда, спасибо за чтение и поделитесь со мной мыслями в Твиттере по адресу: @marinamosti.
P.S.Да здравствует волшебный авокадо! 🥑
P.P.S. ❤️🔥🐶☠️
Благодарю!!! Я наконец-то понял!))
Можно ли деструктурировать второй объект в массиве?
я незнаю