В ES6 деструктуризация присваиваний - это метод, позволяющий извлекать свойства из объектов и массивов и присваивать их каждому из них собственной локальной переменной.

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

Однако деструктуризация дает разработчику множество преимуществ по мере того, как функция становится более сложной, особенно при работе с параметрами функции (подробнее об этом позже).

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

const animals = [“dog”, “cat”, “duck”, “bear”]

До ES6, чтобы получить доступ к значению внутри массива, разработчик должен был использовать значение индекса этого элемента (animals[1] = “cat”). С деструктурированными назначениями разработчик может вместо этого извлекать элементы из массива, назначать их каждый переменной и получать доступ к элементу с помощью этой переменной. Вот так:

const animals = [“dog”, “cat”, “duck”, “bear”]
const [dog, cat, duck, bear] = animals
console.log(dog) // “dog”
console.log(bear) // “bear”

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

const animals = {
  dog: “bark”,
  cat: “meow”,
  duck: “quack”,
  bear: “roar”
}

Чтобы получить доступ к свойству в этом объекте, вы можете использовать точечную нотацию (animals.dog = “bark”).

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

const animals = {
  dog: “bark”,
  cat: “meow”,
  duck: “quack”,
  bear: “roar”
}
const {dog, cat, duck, bear} = animals
console.log(dog) // “bark”
console.log(bear) // “roar”

и так далее.

Вы также можете использовать деструктуризацию с вложенными объектами.

const person = {
  name: “Kevin”,
  age: 28,
  profession: {
    title: “Web Developer”,
    description: “I build cool things on the internet”
   }
}
const { profession: { title } } = person
console.log(title) // “Web Developer”

и с вложенными массивами:

const programmingLanguages = {
  clientSide: “JavaScript”,
  serverSide: [“PHP”, “Ruby”, “Python”, “Go”]
}
const { clientSide, serverSide: [ php, ruby, python, go ] } = languages
console.log(python) // “python”

Есть много других вещей, которые вы можете сделать с деструктуризацией назначений. Однако, как упоминалось ранее, один из лучших вариантов использования - это работа с аргументами функции, особенно в том, что называется объектом параметров. Объект параметров - это отдельный объект, который может содержать или не содержать несколько свойств («параметров») и передается в функцию в качестве параметра. Классическим примером является .ajax метод jQuery.

$.ajax({
  url: “http://someweburl.com/"
})

Здесь .ajax принимает объект в качестве параметра, который содержит именованную переменную “url” со значением “http://someweburl.com/". Это объект параметров.

Итак, представьте, что вы пишете функцию, которая принимает объект параметров, содержащий информацию о марке и модели автомобиля. Это можно было бы написать так:

//Without destructuring
getCar({
  make: “Honda”,
  model: “Accord”
})
function getCar(options) {
  console.log(“The car is a “ + options.make + " " + options.model)  
  // “The car is a Honda Accord”
}

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

//Without destructuring
getCar({
  make: “Honda”
})
function getCar(options) {
  options.model = options.model || “Accord”
  console.log(“The car is a “ + options.make + " " + options.model) 
  // “The car is a Honda Accord”
}

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

//With destructuring
getCar({
  make: “Honda”
})
function getCar(options) {
  let { make, model } = options
  model = model || “Accord”
  console.log(“The car is a “ + make + " " + model) 
  // “The car is a Honda Accord”
}

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

//With destructuring in the method signature
getCar({
  make: “Honda”
})
function getCar({ make, model = “Accord” }) {
  console.log(“The car is a “ + make + " " + model) 
  // “The car is a Honda Accord”
}

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

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