Деструктуризация (destructuring) позволяет извлечь из объекта отдельные значения в переменные или константы:
const user = { name: "Tom", age: 24, phone: "+367438787", email: "tom@gmail.com" }; const {name, email} = user; console.log(name); // Tom console.log(email); // tom@gmail.com
При деструктуризации объекта переменные помещаются в фигурные скобки и им присваивается объект. Сопоставление между свойствами объекта и переменными/константами идет по имени.
Мы можем указать, что мы хотим получить значения свойств объекта в переменные/константы с другим именем:
const user = { name: "Tom", age: 24, phone: "+367438787", email: "tom@gmail.com" }; const {name: userName, email: mailAddress} = user; console.log(userName); // Tom console.log(mailAddress); // tom@gmail.com
В данном случае свойство name сопоставляется с переменной userName, а поле email - с переменной mailAddress.
Также можно задать для переменных/констант значения по умолчанию, если в объекте вдруг не окажется соответствующих свойств:
const user = { name: "Tom", age: 24, }; const {name = "Sam", email: mailAddress = "sam@gmail.com"} = user; console.log(name); // Tom console.log(mailAddress); // sam@gmail.com
Если переменная/константа при деструктуризации сопоставляется со свойством, который представляет сложный объект, то после деструктуризации эта переменная/константа также будет представлять сложный объект:
const user = { name: "Tom", age: 24, account: { login: "tom555", password: "qwerty" } }; const {account} = user; console.log(account.login); // tom555 console.log(account.password); // qwerty
Но если нам мы хотим получить отдельные значения из вложенного сложного объекта, как в примере выше объект account внутри объекта user, то нам необязательно получать весь этот объект - мы также можем для его свойств предоставить отдельные переменные/константы:
const user = { name: "Tom", age: 24, account: { login: "tom555", password: "qwerty" } }; const {name, account: {login}} = user; console.log(name); // Tom console.log(login); // tom555
Здесь мы получаем в переменную login
значение свойства user.account.login
.
rest-оператор или оператор ... позволяет получить оставшиеся свойства объекта, которые не сооставлены с переменными/константами, в отдельную переменную/константу:
const tom = { name: "Tom", age: 24, phone: "+367438787", email: "tom@gmail.com" }; const {name, age, ...contacts} = tom; console.log(name); // Tom console.log(age); // 24 console.log(contacts); // {phone: "+367438787", email: "tom@gmail.com"}
В данном случае мы раскладываем объект tom
на три константы: name
, age
и contacts
.
Константы name и age сопоставляются со свойствами объекта tom
по имени. А константа contacts
получает все оставшиеся несопоставленные
свойства объекта. Однако чтобы их получить, перед названием константы указыватся оператор ...: ...contacts
. То есть
в данном случае константа contacts
будет предлагать объект, который будет содержать свойства email и phone объекта tom.
Стоит отметить, что переменная/константа, которая получает все оставшиеся свойства объекта, всегда будет представлять объект, даже если она получит только одно свойства из объекта.
Также можно разложить массивы:
const users = ["Tom", "Sam", "Bob"]; const [a, b, c] = users; console.log(a); // Tom console.log(b); // Sam console.log(c); // Bob
При деструктуризации массива переменные помещаются в квадратные скобки и последовательно получают значения элементов массива.
Если переменных/констант меньше, чем элементов массива, то оставшиеся элементы массива просто опускаются.
const users = ["Tom", "Sam", "Bob"]; const [a, b] = users; console.log(a); // Tom console.log(b); // Sam
Если переменных/констант больше, чем элементов массива, то несопоставленные переменные/константы получают значение undefined
:
const users = ["Tom", "Sam", "Bob"]; const [a, b, c, d] = users; console.log(a); // Tom console.log(b); // Sam console.log(c); // Bob console.log(d); // undefined
С помощью оператора ... также можно получить все оставшиеся элементы массива в виде другого массива:
const users = ["Tom", "Sam", "Bob", "Mike"]; const [tom, ...others] = users; console.log(tom); // Tom console.log(others); // ["Sam", "Bob", "Mike"]
Здесь массив others
будет содержать три последних элемента массива.
При этом мы можем пропустить ряд элементов массива, оставив вместо имен переменных пропуски:
const users = ["Tom", "Sam", "Bob", "Ann", "Alice", "Kate"]; const [first,,,,fifth] = users; console.log(first); // Tom console.log(fifth); // Alice
Выражение first,,,,fifth
указывает, что мы хотим получить первый элемент массива в переменную first, затем пропустить три элемента и
получить пятый элемент в переменную fifth.
Подобным образом можно получить, например, второй и четвертый элементы:
const users = ["Tom", "Sam", "Bob", "Ann", "Alice", "Kate"]; const [,second,,forth] = users; console.log(second); // Sam console.log(forth); // Ann
const coordinates = [[1,2,3], [4,5,6], [7,8,9]]; const [ [x1,y1,z1], [x2,y2,z2], [x3,y3,z3] ] = coordinates;
Можно совместить получение данных из массива и объекта:
const people = [ {name: "Tom", age: 34}, {name: "Bob", age: 23}, {name: "Sam", age: 32} ]; const [,{name}] = people; console.log(name); // Bob
В данном случае получаем значение свойства name второго объекта в массиве.
Другой пример - деструктуризация объектов при переборе массива объектов:
const people = [ {name: "Tom", age: 34}, {name: "Bob", age: 23}, {name: "Sam", age: 32} ]; const [,{name}] = people; for(let {name: username, age: userage} of people){ console.log(`Name: ${username} Age: ${userage}`); } // консольный вывод // Name: Tom Age: 34 // Name: Bob Age: 23 // Name: Sam Age: 32
Если в функцию в качестве параметра передается массив или объект, то его также можно подобным образом разложить на отдельные значения:
function display({name:userName, age:userAge}){ console.log(userName, userAge); } function sum([a, b, c]){ const result = a + b + c; console.log(result); } const user = {name:"Alice", age:33, email: "alice@gmail.com"}; const numbers = [3, 5, 7, 8]; display(user); // Alice 33 sum(numbers); // 15
Благодаря деструктуризации очень просто стало проводить обмен значениями между двумя переменными:
let first = "Tom"; let second = "Bob"; [first, second] = [second, first]; console.log(first); // Bob console.log(second); // Tom
Что упрощает решение ряда задач. Например, используем деструктуризацию для простейшей сортировки массива:
let nums = [9, 3, 5, 2, 1, 4, 8, 6]; for(let i = 0; i < nums.length; i++) for(let j = 0; j < nums.length; j++) if (nums[i] < nums[j]) [nums[j], nums[i]] = [nums[i], nums[j]]; console.log(nums); // [1, 2, 3, 4, 5, 6, 8, 9]