JavaScript Destructuring Assignment

Объект и Массив - это две часто используемые структуры данных JavaScript.

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

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

Литеральные выражения объекта и массива позволяют создавать ад hoc пакеты. Вот синтаксис:

const x = [1, 2, 3, 4, 5];

Операция деструктуризации - это уникальный синтаксис, который помогает "распаковывать" объекты или массивы в группы переменных. Деструктуризация также может эффективно работать со сложными функциями, значениями по умолчанию и другими.

Деструктивное присваивание использует следующий синтаксис:

Javascript arrays destructuring
const x = [1, 2, 3, 4, 5]; const [y, z] = x; console.log(y); // 1 console.log(z); // 2

Вы можете найти аналогичные функции и в других языках. Например, в Python или Perl.

Теперь давайте посмотрим на пример деструктуризации массива в переменные:

Javascript arrays destructuring
// we have an array with the name and surname let arr = ["John", "Doe"]; // destructuring assignment // sets firstname = arr[0] // and surname = arr[1] let [firstname, surname] = arr; console.log(firstname); // John console.log(surname); // Doe

В результате можно работать с переменными вместо членов массива.

Это будет работать еще лучше, если вы совместите его с split или другими методами, возвращающими массив:

let [firstName, surname] = "John Doe".split(' ');

Обратите внимание, что деструктуризация не то же самое, что и "деструктивная".

Мы называем это деструктуризацией, потому что она "деструктурирует" путем копирования элементов в переменные.

Вот более короткий способ записи:

// let [firstName, surname] = arr;
let firstName = arr[0];
let surname = arr[1];

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

Javascript arrays destructuring
// second element is not needed let [name, age , profession] = ["David", "23", "programmer"]; console.log(profession); // programmer

Это может работать с любым итерируемым элементом справа:

let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);

Кроме того, вы можете использовать любые присваиваемые элементы слева.

Например, свойство объекта:

Javascript arrays destructuring
let user = {}; [user.name, user.surname] = "John Doe".split(' '); console.log(user.name); // John

Еще одна полезная вещь - это возможность использовать метод Object.entries(obj) с деструктуризацией для перебора ключей и значений объекта.

Вот пример:

Javascript object entries method with destructuring
let user = { name: "Maria", age: 25 }; // loop over keys-and-values for (let [key, value] of Object.entries(user)) { console.log(`${key}:${value}`); // name:Maria, then age:25 }

Оставшийся ‘…’

Если вам нужно получить не только первые значения, но и собрать все последующие, у вас есть возможность добавить еще один параметр для получения “остальных”, просто используя три точки “…”, вот так:

Javascript arrays rest
let [name1, name2, ...rest] = ["John", "Doe", "doctor", "surgeon"]; console.log(name1); // John console.log(name2); // Doe // Note that type of `rest` is Array. console.log(rest[0]); // doctor console.log(rest[1]); // surgeon console.log(rest.length); // 2

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

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

Javascript arrays rest
let [firstName, surname] = []; console.log(firstName); // undefined console.log(surname); // undefined

Если вы хотите значение по умолчанию для замены пропущенного, используйте знак =, как это:

Javascript arrays rest
// default values let [name = "David", surname = "Smith"] = ["Peter"]; console.log(name); // Peter (from array) console.log(surname); // Smith (default used)

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

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

let {  var1,  var2} = {  var1: …,  var2: …}

Справа находится существующий объект, который необходимо разделить на переменные. Слева - шаблон для сопоставления свойств. Знак три точки {...} включает группу имен переменных.

Вот пример:

Javascript arrays destructuring an object
let options = { title: "Car", model: "BMW M5", year: 2020 }; let { title, model, year } = options; console.log(title); // Car console.log(model); // BMW M5 console.log(year); // 2020

Свойства options.title, options.width и options.height назначаются соответствующим переменным. Порядок не имеет значения. Этот вариант также будет работать:

// changed the order in let {...}
let {
  year,
  model,
  title
} = {
  title: "Car",
  model: "BMW M5",
  year: 2020
}

Для присвоения свойства переменной с другим именем, вы можете поступить так:

Javascript arrays destructuring an object
let options = { title: "Car", model: "BMW M5", year: 2020 }; // { sourceProperty: targetVariable } let { model: m, year: y, title } = options; // width -> m // height -> y // title -> title console.log(title); // Car console.log(m); // BMW M5 console.log(y); // 2020

Для возможно отсутствующих свойств, у вас есть возможность установить значения по умолчанию, используя знак “=”, как следует:

Javascript arrays destructuring an object
let options = { title: "Car" }; let { model = "BMW M5", year = 2020, title } = options; console.log(title); // Car console.log(model); // BMW M5 console.log(year); // 2020

Значения по умолчанию могут быть любыми выражениями или вызовами функций.

В случае сложного объекта с рядом свойств, вы можете выбрать то, что вам нужно, как следует:

Javascript arrays destructuring an object
let options = { title: "Car", model: "BMW M5", year: 2020 }; // only extract title as a variable let { title } = options; console.log(title); // Car

Оставшойся шаблон “…”

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

Вот пример:

Javascript arrays destructuring an object
let options = { title: "Book", page: 200, species : "scientific" }; // title = property named title // rest = object with the rest of properties let { title, ...rest } = options; // now title="Book", rest={page: 200, species: scientific} console.log(rest.page); // 200 console.log(rest.species); // scientific

Вложенная деструктуризация

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

В приведенном ниже примере, options содержит другой объект в свойстве views и массив в свойстве items:

Javascript arrays nested destructuring an object
let options = { views: { model: "sport", year: 2020 }, items: ["Car", "Bike"], extra: true }; // destructuring assignment split in multiple lines for clarity let { views: { // put size here model, year }, items: [item1, item2], // assign items here title = "Car&Bike" // not present in the object (default value is used) } = options; console.log(title); // Car&Bike console.log(model); // sport console.log(year); // 2020 console.log(item1); // Car console.log(item2); // Bike

Важно знать, что все свойства объекта options, кроме extra (его нет на левой стороне), присваиваются соответствующим переменным.

Так, model, year, item1, item2, и title имеют одинаковое значение. Но нет переменных для views и items.

Параметры умной функции

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

Мы не рекомендуем вам писать функцию так:

function showBook(title = "Javascript", page = 200,  species : "programming"
, items = []) {
  // ...
}

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

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

Javascript arrays
// we pass object to function let options = { title: "Js book", items: ["Item1", "Item2"] }; function showBook({ title = "Javascript", pages = 200, species = "programming", items = [] }) { // title, items – taken from options, // pages, species – defaults used console.log(`${title} ${species} ${pages}`); // Javascript programming 200 console.log(items); // Item1, Item2 } showBook(options);

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

Например:

Javascript arrays
let options = { title: "Js book" }; function showBook({ title = "Javascript", p = 200, //pages goes to p s = "programming", // species goes to s }) { console.log(`${title} ${s} ${p}`); // Javascript programming 200 } showBook(options);

Полный синтаксис выглядит так:

function ({
  incomingProperty: varName = defaultValue
    ...
})

Как вы можете видеть, это то же самое, что и для деструктуризации присваивания.

Затем, для объекта параметров, будет переменная varName для incomingProperty.

Такую деструктуризацию считают, что у showBook() нет аргумента. Если вы хотите все значения по умолчанию, тогда укажите пустой объект, вот так:

showBook({}); // ok, all values are default
showBook(); // this would give an error

Вы можете исправить это, установив {} значение по умолчанию объекту параметров.

Например:

Javascript arrays
function showBook({ title = "Book", species = "programming", pages = 200 } = {}) { console.log(`${title} ${species} ${pages}`); } showBook(); // Book programming 200

Время Викторины: Проверьте Свои Навыки!

отовы проверить свои знания? Погрузитесь в наши интерактивные викторины для более глубокого понимания и веселого способа закрепить знания.

Считаете ли это полезным?