Как стать автором
Обновить
0
Skillbox
Образовательная платформа Skillbox

Пишем чистый код при помощи деструктуризации объектов в JavaScript

Время на прочтение4 мин
Количество просмотров14K
Автор оригинала: Asel Siriwardena

Сравниваем традиционный способ извлечения значений и деструктуризацию (ES6) в JavaScript

В этой статье мы рассмотрим традиционное присваивание значений из объектов в переменные и новый синтаксис деструктуризации в ES6. Материал адаптирован на русский язык совместно с тимлидом группы frontend-разработки в Skillbox Иваном Казанцевым.

Деструктуризация — это синтаксис, который позволяет распаковывать значения из массивов или свойства из объектов в переменные.

Что нам это дает? Возможность писать более чистый и понятный код, экономя время и количество строк.

Деструктуризация объектов

Сначала рассмотрим деструктуризацию объектов. И для примера возьмем объект - клиент (customer).

const customer = {
  name: 'Sherlock',
  email: 's.h.@gmail.com',
  age: 34,
  address: {
    streetNo: '221b Baker Street',
    city: 'London',
    country: 'UK'
  }
}

Базовое присвоение переменной

Если бы нам нужно было достать из него name и email, привычным способом мы бы сделали так:

const name = customer.name;
const email = customer['email']; // или так

console.log(name); // Sherlock
console.log(email); // s.h@gmaill.com

С помощью деструктуризации мы можем делать так:

const { name, email } = customer;

console.log(name); // Sherlock
console.log(email); // s.h@gmaill.com

Как минимум, мы уже не пишем два раза customer и чувствуем себя чуть-чуть лучше, так как можем добавить в резюме что-то про DRY.

Но если мы хотим записать customer.name в переменную с другим именем, выходит, снова нужен традиционный способ? Нет, это мы тоже можем сделать:

const { name: customerName, email } = customer;

// обратите внимание, имя свойства из объекта customer находится слева
console.log(customerName); // Sherlock

Присвоение значений объявленным переменным

Если мы хотим присвоить значения уже существующим переменным, делаем почти тоже самое, но добавляем ().

let name, email;

({ name, email } = customer);

console.log(name);
console.log(email);

Почему мы добавляем ()?

{ в левой части считается блоком, а не литералом объекта. Если опустите (), вы получите сообщение об ошибке:

{ name, email } = customer;
            	^SyntaxError: Unexpected token '='

Вложенные объекты

Итак, мы поняли, что это удобно, можем усложнять. Если хотим получить доступ к свойствам city и country, в традиционном способе нам нужно использовать цепочку обращений:

const name = customer.name;
const streetNo = customer.address.streetNo;
const city = customer['address']['city']; // или так

console.log(name); // Sherlock
console.log(streetNo); // 221b Baker Street
console.log(city); // London

Мы можем сделать то же самое, но короче, используя деструктуризацию:

const { name, address: { streetNo, city } } = customer;

console.log(name); // Sherlock
console.log(streetNo); // 221b Baker Street
console.log(city); // UK

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

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

Идем дальше. Теперь перед нами стоит задача: добавить married (женат/замужем) нашему объекту customer. Возможные варианты ответа: “да” (yes) или “нет” (no). В случае, если не указан, присвоить значение “нет ответа” (N/A).

Без деструктуризации мы бы сделали так:

let married = customer.married;

console.log(married); // undefined

if (!married) {
  married = 'N/A';
}
console.log(married); // N/A

Но с деструктуризацией мы можем объявлять значения по умолчанию, тем самым избавиться от условия. Фантастика?

const { name, married = 'N/A' } = customer;

console.log(name); // Sherlock
console.log(married); // N/A

Остаточные параметры объекта

Представим, что нам нужно достать только name ( например, чтобы присвоить ему значение по умолчанию), а все остальное записать “как есть” в другую переменную.

const { name = 'Спрятался в коробке', ...rest } = customer;

console.log(name); // Sherlock
console.log(rest);
// {
//  email: 's.h@gmaill.com',
//  age: null,
//  address: { streetNo: '221b Baker Street', city: 'London', country: 'UK' }
// }

Обратите внимание, вместо rest вы можете использовать любое другое название переменной, просто не забудьте поставить ... и расположить это в конце.

Деструктуризация null

Стоит иметь ввиду, чтоnull деструктурировать нельзя, мы получим ошибку:

function getCustomer() {
return null;
}

let { name, email } = getCustomer();
// TypeError: Cannot destructure property name of 'undefined' or 'null'.

Поэтому мы должны обрабатывать такие случаи, например, так:

let { name = 'Спрятался в коробке', email = null } = getCustomer() || {};

console.log(name, email); // Спрятался в коробке null

Деструктуризация аргументов функции

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

Как бы мы сделали ранее:

let display = (customer) => console.log(`${customer.name} ${customer.address.city}`);

display(customer); // Sherlock London

Как мы сделаем теперь:

let display = ( { name, address: { city } } ) => console.log(`${name} ${city}`);  

display(customer); // Sherlock London

Деструктуризация массивов

Да, это работает и с массивами. Для примера нам понадобится пакет с фруктами.

const fruits = ['Banana', 'Orange', 'Apple', 'Mango'];

Базовая деструктуризация массива

Если бы нам нужно было достать банан и апельсин, ранее мы бы сделали следующее:

let firstFruit = fruits[0];
let secondFruit = fruits[1];

console.log(firstFruit); // Banana
console.log(secondFruit); // Orange

Но не сегодня, сегодня мы познакомились с деструктуризацией!

let [firstFruit, secondFruit, thirdFruit] = fruits;

console.log(firstFruit); // Banana
console.log(secondFruit); // Orange
console.log(thirdFruit); // Apple (да, мы можем позволить себе и третий фрукт, потому что мы молодцы)

Пропуск пунктов

В объектах мы могли доставать любые значения свойств по имени и записывать их в переменные. А что, если мы хотим достать только первый и третий фрукт из массива? Нам просто нужно добавить лишнюю запятую.

let [firstFruit, , thirdFruit] = fruits;

Да-да, мы не указываем название переменной, и второй элемент пропускается.

Остаточные параметры массива

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

let [yourFav, , ...friendsFav] = fruits;

console.log(yourFav); // Banana
console.log(friendsFav); // [ 'Apple', 'Mango' ]

Замена значений

И в конце — фокус. Сейчас мы поменяем местами первый и второй фрукт, не объявляя для этого новую переменную.

let [firstFruit, secondFruit] = fruits;

console.log(firstFruit); // Banana
console.log(secondFruit); // Orange

[firstFruit, secondFruit] = [secondFruit, firstFruit]

console.log(firstFruit); // Orange
console.log(secondFruit); // Banana

Ловкость деструктуризации и никакого мошенничества.

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

Теги:
Хабы:
+16
Комментарии20

Публикации

Информация

Сайт
skillbox.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия

Истории