Когда вы делаете запрос к Stripe API, приходит большой объект: { id, amount, currency, customer: { id, email, name }, metadata: {...} }. Без деструктуризации нужно писать response.customer.email, response.customer.name десятки раз. Деструктуризация позволяет извлечь нужные поля в переменные за одну строку.
obj.field.subfield...rest в деструктуризации (забегаем вперёд: тот же синтаксис)const user = { name: 'Алексей', age: 28, role: 'admin', city: 'Москва' }
// Базовое — извлекаем нужные поля
const { name, age } = user
console.log(name, age) // 'Алексей' 28
// Переименование — новое имя переменной после :
const { name: userName, role: userRole } = user
console.log(userName, userRole) // 'Алексей' 'admin'
// Значение по умолчанию — если поля нет или оно undefined
const { city, country = 'Россия' } = user
console.log(city, country) // 'Москва' 'Россия'
// Вложенные объекты
const response = { data: { user: { email: 'alex@mail.ru' } } }
const { data: { user: { email } } } = response
console.log(email) // 'alex@mail.ru'
// Остаток через ...rest
const { name: n, ...rest } = user
console.log(rest) // { age: 28, role: 'admin', city: 'Москва' }const colors = ['red', 'green', 'blue', 'yellow']
// Базовое — позиции важны, не имена
const [first, second] = colors
console.log(first, second) // 'red' 'green'
// Пропуск элементов — запятые без переменной
const [, , third] = colors
console.log(third) // 'blue'
// Значение по умолчанию
const [a, b, c, d, e = 'white'] = colors
console.log(e) // 'white' — пятого элемента нет
// Остаток
const [head, ...tail] = colors
console.log(head) // 'red'
console.log(tail) // ['green', 'blue', 'yellow']
// Обмен переменных без temp
let x = 1, y = 2
;[x, y] = [y, x]
console.log(x, y) // 2 1Очень часто в реальном коде — самодокументирующие параметры с дефолтами:
// Вместо function createUser(name, role, theme, fontSize)
function createUser({ name, role = 'user', theme = 'dark', fontSize = 14 } = {}) {
console.log(`Создан: ${name} [${role}]`)
}
createUser({ name: 'Иван' })
// Создан: Иван [user]
createUser({ name: 'Мария', role: 'admin', theme: 'light' })
// Создан: Мария [admin]Ошибка 1: деструктуризация null/undefined
// Сломано:
const { name } = null // TypeError: Cannot destructure property 'name' of null
// Исправлено — значение по умолчанию для всего объекта:
const { name } = null ?? {} // name = undefined
const { name = 'Гость' } = null ?? {} // name = 'Гость'Ошибка 2: путаница переименования и значения по умолчанию
// Это переименование: новая переменная называется 'userName'
const { name: userName } = user
// Это значение по умолчанию:
const { name = 'Гость' } = user
// Оба вместе:
const { name: userName = 'Гость' } = userОшибка 3: деструктуризация в цикле — повторное объявление
// Сломано:
for (const item of items) {
const { name } = item // OK — const создаётся заново в каждой итерации
}
// Но вне цикла нельзя объявить дважды:
const { name } = item1
const { name } = item2 // SyntaxError: Identifier 'name' has already been declared
// Исправлено — переименование:
const { name: name1 } = item1
const { name: name2 } = item2const { data, loading, error } = useQuery()const { PORT = 3000, DB_URL } = process.envconst { results: products, total, page } = await fetchProducts()import { useState, useEffect } from 'react' — тоже деструктуризацияОбработка ответа платёжного API (Stripe-подобный)
// Симуляция ответа платёжного API
const paymentResponse = {
id: 'pay_3N8abc',
status: 'succeeded',
amount: 149900, // в копейках
currency: 'rub',
customer: {
id: 'cus_X7zZ',
email: 'buyer@example.com',
name: 'Алексей Смирнов',
address: {
city: 'Москва',
street: 'ул. Тверская, 1',
}
},
metadata: {
orderId: 'ORD-2024-001',
promoCode: 'WINTER20',
},
fees: [150, 75, 25]
}
// Деструктуризация вложенного объекта
const {
id: paymentId,
status,
amount,
currency,
customer: {
email,
name: customerName,
address: { city }
},
metadata: { orderId, promoCode = null },
fees: [mainFee, ...otherFees],
} = paymentResponse
console.log(paymentId) // 'pay_3N8abc'
console.log(status) // 'succeeded'
console.log(customerName) // 'Алексей Смирнов'
console.log(city) // 'Москва'
console.log(orderId) // 'ORD-2024-001'
console.log(promoCode) // 'WINTER20'
console.log(mainFee) // 150
console.log(otherFees) // [75, 25]
console.log((amount / 100).toFixed(2) + ' ' + currency) // '1499.00 rub'
// Деструктуризация в параметрах функции
function sendReceipt({ email, name: customerName, address: { city } = {} }) {
console.log(`Квитанция отправлена ${customerName} (${email}) из ${city}`)
}
sendReceipt(paymentResponse.customer)
// Квитанция отправлена Алексей Смирнов (buyer@example.com) из МоскваКогда вы делаете запрос к Stripe API, приходит большой объект: { id, amount, currency, customer: { id, email, name }, metadata: {...} }. Без деструктуризации нужно писать response.customer.email, response.customer.name десятки раз. Деструктуризация позволяет извлечь нужные поля в переменные за одну строку.
obj.field.subfield...rest в деструктуризации (забегаем вперёд: тот же синтаксис)const user = { name: 'Алексей', age: 28, role: 'admin', city: 'Москва' }
// Базовое — извлекаем нужные поля
const { name, age } = user
console.log(name, age) // 'Алексей' 28
// Переименование — новое имя переменной после :
const { name: userName, role: userRole } = user
console.log(userName, userRole) // 'Алексей' 'admin'
// Значение по умолчанию — если поля нет или оно undefined
const { city, country = 'Россия' } = user
console.log(city, country) // 'Москва' 'Россия'
// Вложенные объекты
const response = { data: { user: { email: 'alex@mail.ru' } } }
const { data: { user: { email } } } = response
console.log(email) // 'alex@mail.ru'
// Остаток через ...rest
const { name: n, ...rest } = user
console.log(rest) // { age: 28, role: 'admin', city: 'Москва' }const colors = ['red', 'green', 'blue', 'yellow']
// Базовое — позиции важны, не имена
const [first, second] = colors
console.log(first, second) // 'red' 'green'
// Пропуск элементов — запятые без переменной
const [, , third] = colors
console.log(third) // 'blue'
// Значение по умолчанию
const [a, b, c, d, e = 'white'] = colors
console.log(e) // 'white' — пятого элемента нет
// Остаток
const [head, ...tail] = colors
console.log(head) // 'red'
console.log(tail) // ['green', 'blue', 'yellow']
// Обмен переменных без temp
let x = 1, y = 2
;[x, y] = [y, x]
console.log(x, y) // 2 1Очень часто в реальном коде — самодокументирующие параметры с дефолтами:
// Вместо function createUser(name, role, theme, fontSize)
function createUser({ name, role = 'user', theme = 'dark', fontSize = 14 } = {}) {
console.log(`Создан: ${name} [${role}]`)
}
createUser({ name: 'Иван' })
// Создан: Иван [user]
createUser({ name: 'Мария', role: 'admin', theme: 'light' })
// Создан: Мария [admin]Ошибка 1: деструктуризация null/undefined
// Сломано:
const { name } = null // TypeError: Cannot destructure property 'name' of null
// Исправлено — значение по умолчанию для всего объекта:
const { name } = null ?? {} // name = undefined
const { name = 'Гость' } = null ?? {} // name = 'Гость'Ошибка 2: путаница переименования и значения по умолчанию
// Это переименование: новая переменная называется 'userName'
const { name: userName } = user
// Это значение по умолчанию:
const { name = 'Гость' } = user
// Оба вместе:
const { name: userName = 'Гость' } = userОшибка 3: деструктуризация в цикле — повторное объявление
// Сломано:
for (const item of items) {
const { name } = item // OK — const создаётся заново в каждой итерации
}
// Но вне цикла нельзя объявить дважды:
const { name } = item1
const { name } = item2 // SyntaxError: Identifier 'name' has already been declared
// Исправлено — переименование:
const { name: name1 } = item1
const { name: name2 } = item2const { data, loading, error } = useQuery()const { PORT = 3000, DB_URL } = process.envconst { results: products, total, page } = await fetchProducts()import { useState, useEffect } from 'react' — тоже деструктуризацияОбработка ответа платёжного API (Stripe-подобный)
// Симуляция ответа платёжного API
const paymentResponse = {
id: 'pay_3N8abc',
status: 'succeeded',
amount: 149900, // в копейках
currency: 'rub',
customer: {
id: 'cus_X7zZ',
email: 'buyer@example.com',
name: 'Алексей Смирнов',
address: {
city: 'Москва',
street: 'ул. Тверская, 1',
}
},
metadata: {
orderId: 'ORD-2024-001',
promoCode: 'WINTER20',
},
fees: [150, 75, 25]
}
// Деструктуризация вложенного объекта
const {
id: paymentId,
status,
amount,
currency,
customer: {
email,
name: customerName,
address: { city }
},
metadata: { orderId, promoCode = null },
fees: [mainFee, ...otherFees],
} = paymentResponse
console.log(paymentId) // 'pay_3N8abc'
console.log(status) // 'succeeded'
console.log(customerName) // 'Алексей Смирнов'
console.log(city) // 'Москва'
console.log(orderId) // 'ORD-2024-001'
console.log(promoCode) // 'WINTER20'
console.log(mainFee) // 150
console.log(otherFees) // [75, 25]
console.log((amount / 100).toFixed(2) + ' ' + currency) // '1499.00 rub'
// Деструктуризация в параметрах функции
function sendReceipt({ email, name: customerName, address: { city } = {} }) {
console.log(`Квитанция отправлена ${customerName} (${email}) из ${city}`)
}
sendReceipt(paymentResponse.customer)
// Квитанция отправлена Алексей Смирнов (buyer@example.com) из МоскваПришёл ответ от API погоды. Напиши функцию formatWeather(data), которая деструктурирует объект data и возвращает отформатированную строку. Функция должна брать: город (city), температуру (temp), ощущаемую температуру (feelsLike из поля feels_like), описание (первый элемент массива weather), скорость ветра (wind.speed). Если описание отсутствует — использовать 'нет данных'.
Для первого элемента массива weather с дефолтом: const [{ description } = {}] = data.weather. Если массив пуст — деструктуризация даст undefined, тогда description ?? "нет данных".