Что такое деструктуризация в JS?

Деструктуризация помогает сделать сложную структуру более простой, разделить (деструктурировать) на более мелкие части, например, объект.

Деструктуризация появилась в стандарте ES6. Поддержку этой «фичи» в разных браузерах можно посмотреть тут.

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

Простой пример:

const obj = {
  firstName: 'John',
  lastName: 'Doe',
  age: 28 
}

const { firstName, lastName, age } = obj;

// Вместо определения каждой переменной по отдельности
// const firstName = obj.firstName;
// const lastName = obj.lastName;
// ...

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

const { firstName: name } = obj;

console.log(name); // John
console.log(firstName); // Uncaught ReferenceError: firstName is not defined

В коде выше мы вытаскиваем свойство firstName из объекта obj и присваиваем его в переменную name

Деструктуризация вложенных объектов

Принцип тот же, только вытаскиваем свойство не из родительского объекта, а из его вложенного объекта.

const obj = {
    firstName: 'John',
    lastName: 'Doe',
    bio: {
      birth: '20.08.1994',
      age: 28,
      hasWork: true,
      isMarried: false
    }
}

const { birth, age, hasWork, isMarried } = obj.bio;

Также если вам необходимо получить не только вложенные свойства. Допустим из примера выше, вам нужны firstName и age:

const { firstName, bio: { age } } = obj;

console.log(firstName, age); // John 28

Также и переменную age можно «переназвать»:

const { firstName, bio: { age: someVar } } = obj;

console.log(firstName, someVar); // John 28

Тут главное конечно не переборщить… чтобы код оставался понятным и читаемым.

Если вы будете работать с обработчиками событий в JS, они могут получать event, в котором есть много вложенных объектов. Допустим у нас есть инпут и для его обработки есть функция хендлер, чтобы вытащить данные из event мы можем использовать деструктуризацию:

function eventHandler(e) {
  const [name, value] = e.target;
  console.log(name, value);
  // ...
}

Значение по умолчанию (дефолтные) при деструктуризации

Если вы не уверены в наличии какого-либо свойства в объекте, вы можете установить значение по умолчанию:

const obj = {
    firstName: 'John',
    lastName: 'Doe',
    age: 28
}

const { isMarried = false } = obj;

console.log(isMarried); // false

Если свойство в объекте было бы указано и имело бы какое-либо значение (возможно даже null, false или 0), то в консоль бы вывелось это значение, т.к. значение по умолчанию в таком случае присвоено не будет:

const obj = {
    firstName: 'John',
    lastName: 'Doe',
    age: null,
    isMarried: true
}

const { age = 20, isMarried = false } = obj;

console.log(age, isMarried); // null true

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

Работает также, но тут будет важен порядок указываемых переменных. проще это будет рассмотреть на примере:

const arr = ['Apple', 'Potato'];

const [fruit, vegetable] = arr;

console.log(fruit); // Apple
console.log(vegetable); // Potato

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

const arr = ['Apple', 'Potato'];

const [vegetable, fruit] = arr;

console.log(fruit); // Potato
console.log(vegetable); // Apple

На практике данный метод используется например в React Hook useState()

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

const fruits = ['Apple', 'Kiwi'];
const [fruit_1] = fruits; // будет присвоен только Apple

const vegetables = ['Potato'];
const [vegetable_1, vegetable_2] = vegetables;

console.log(vegetable_1, vegetable_2); // 'Potato', undefined

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

const arr = ['Apple', 'Kiwi', 'Banana', 'Orange', 'Lime'];

const [fruit_0,,, fruit_3] = arr; // пропускаем 2 элемента

console.log(fruit_0, fruit_3); // Apple Orange

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

const arr = ['Apple', ['Kiwi', 'Orange']];

const [fr1, [fr2, fr3]] = arr;

console.log(fr1, fr2, fr3); // Apple Kiwi Orange

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

Данный метод очень часто используется на практике. Если вы работали с React, например, то знаете, что в компоненты могут передаваться пропсы (props). В самом компоненте вы можете сделать деструктуризацию уже внутри функции или на этапе получения параметров функции:

const App = (props) => {
  const { name, age } = props;
}

const App = ({ name, age }) => {
  //...
}

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

Можно разбить строку на символы:

const [one, two, three] = 'abc';

console.log(one, two, three); // a b c

Ваши вопросы и комментарии: