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