В прошлых курсах мы узнали о деструктуризации массивов и объектов, попутно заметив, что эту технику можно применять везде, где явно или неявно подразумевается присвоение массивов или объектов. Пришло время разобраться, как это происходит при вызове функций. Когда мы передаём аргумент при вызове, его значение присваивается формальному параметру функции. Это неявное автоматическое присвоение, потому что в коде этой операции "не видно".

const func = (x) => {
  // параметру x будет присвоено
  // значение аргумента при вызове функции
  console.log(x);
};

func(1); // => 1
// Это можно представить так, что
// внутри функции создаётся параметр x,
// которому присваивается значение аргумента:
// {
//   let x = 1;
//   console.log(x);
// };

func([1, 2]); // => [1, 2]
// Пример с передачей массива:
// {
//   let x = [1, 2];
//   console.log(x);
// };

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

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

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

Не самый выразительный вариант — прямое обращение к элементам массива по индексам:

const func = (arr) => {
  console.log(arr[0]);
  console.log(arr[1]);
};

// let arr = [1, 2];
func([1, 2]);
// => 1
// => 2

Более интересный вариант — дестракчеринг массива в теле функции:

const func = (arr) => {
  const [first, second] = arr;
  console.log(first);
  console.log(second);
};

// let arr = [1, 2];
func([1, 2]);
// => 1
// => 2

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

const func = ([first, second]) => {
  console.log(first);
  console.log(second);
};

// let [first, second] = [1, 2];
func([1, 2]);
// => 1
// => 2

При этом действуют все стандартные правила деструктуризации массива:

const arr = [1, 2];

// let [first, second] = arr;
func(arr);
// => 1
// => 2

// let [first, second] = [1];
func([1]);
// => 1
// => undefined

// let [first, second] = [];
func([]);
// => undefined
// => undefined

Если в передаваемом массиве меньше двух элементов, параметрах, которым "не хватило" соответствующих значений будут содержать undefined. Для таких случаев можно подстраховаться и задать значение по умолчанию:

const func = ([first = 666, second = 777]) => {
  console.log(first);
  console.log(second);
};

// [first = 666, second = 777] = [1];
func([1]);
// => 1
// => 777


// [first = 666, second = 777] = [];
func([])
// => 666
// => 777

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

Напишем функцию, которая принимает на вход объект с информацией об имени и фамилии пользователя и выводит их в терминал. Сразу реализуем вариант с деструктуризацией объекта для параметров:

const func = ({ name, surname }) => {
  console.log(name);
  console.log(surname);
};

// let { name, surname } = { name: 'John', surname: 'Doe' };
func({ name: 'John', surname: 'Doe' });
// => John
// => Doe

Типичная ситуация на практике, когда на вход функции приходит объект с большим количеством свойств, но фактически нужны значения не всех свойств, а всего нескольких. Например, это бывает при обработке ответа (response) от сервера или конфигурации для программы. В таких случаях мы забираем только нужные значения — ведь при дестракчеринге необязательно указывать все свойства объекта. Модифицируем наш пример, мы знаем, что аргументом приходит объект с именем и фамилией, но теперь нам нужна только фамилия:

const func = ({ surname }) => {
  // берём только значения surname
  console.log(surname);
};

const obj = { name: 'John', surname: 'Doe' };

// let { surname } = { name: 'John', surname: 'Doe' };
func(obj); // => Doe

Прочее

Повторю ещё раз мысль о том, что деструктуризация для параметров функции работает стандартно, как и во всех других ситуациях, где ожидается объект, который можно деструктурировать. И все фишки, вроде значений по умолчанию, дестракчеринг вложенных (объекты, содержащие объекты; массивы, содержащие массивы) и составных (объекты, содержащие массивы, и наоборот) элементов, можно применить в случае передачи аргументов функции. Если что-то подзабыли, то вернитесь к соответствующим урокам из курсов про массивы или объекты, ссылки в разделе "Дополнительные материлы". А самый верный и эффективный способ разобраться — поэкспериментировать с кодом в локальной или онлайн-песочнице.


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

  1. Урок из курса JS: Массивы про деструктуризацию
  2. Урок из курса JS: Объекты про деструктуризацию
Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Node, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →