Default Values and Renaming
Two features of destructuring make it more powerful in practice: default values when a property might be missing, and renaming when the property name conflicts with an existing variable or is not descriptive enough.
Default values in destructuring
Section titled “Default values in destructuring”If a property does not exist on the object (or is undefined), destructuring assigns undefined to the variable. Add a default value with = to provide a fallback:
const expense = { description: 'Coffee', amount: 4.50 };
const { description, category = 'Uncategorized' } = expense;console.log(category); // 'Uncategorized' — property was missing, default kicks inDefaults only apply when the value is undefined — not when it is null, 0, or '':
const { amount = 10 } = { amount: 0 };console.log(amount); // 0 — 0 is not undefined, so the default does not applyDefaults in function parameters
Section titled “Defaults in function parameters”You saw defaults in the Expense constructor:
constructor({ category = 'Other', date = new Date().toISOString().split('T')[0] } = {}) { // ...}The = {} at the end of the parameter handles the case where the function is called with no argument at all — without it, destructuring undefined would throw an error.
Renaming on destructure
Section titled “Renaming on destructure”Use : to assign a property to a differently-named variable:
const expense = { id: 1, description: 'Coffee', amount: 4.50 };
const { id: expenseId, description: name } = expense;console.log(expenseId); // 1console.log(name); // 'Coffee'// id and description are not declared — only expenseId and nameThe syntax reads as: “take the id property and call it expenseId.”
Combining renaming and defaults
Section titled “Combining renaming and defaults”You can rename and provide a default in a single expression:
const { category: cat = 'Uncategorized' } = expense;// Rename 'category' to 'cat', defaulting to 'Uncategorized' if missingRead it as: “take the category property, call it cat, and use 'Uncategorized' if it is not there.”
Common use cases in BudgetBuddy
Section titled “Common use cases in BudgetBuddy”Handling API response shapes — the ExchangeRate-API returns data.rates. Destructuring with a rename and default keeps the code readable:
const { rates = {} } = apiResponse;const { USD = 1, EUR = 0, GBP = 0 } = rates;Merging objects safely — when you update an expense, you apply only the changed fields, defaulting everything else to the existing value:
function updateExpense(existing, changes) { const { description = existing.description, amount = existing.amount, category = existing.category } = changes; return { ...existing, description, amount, category };}Destructuring in for…of
Section titled “Destructuring in for…of”Destructuring works in loop variable positions too:
const expenses = [ { id: 1, description: 'Coffee', amount: 4.50 }, { id: 2, description: 'Lunch', amount: 12.75 },];
for (const { id, description } of expenses) { console.log(`${id}: ${description}`);}// 1: Coffee// 2: LunchExercise
Section titled “Exercise”Using the BudgetBuddy expenses data:
- Destructure
categoryfrom an expense that does not have it, providing'Other'as the default. - Destructure
idbut rename it toexpenseId. Confirm thatidis not declared, onlyexpenseId. - Write a function
display({ description, amount: cost = 0 })that uses both renaming and a default. Call it with an expense missing anamount. - Use
for...ofwith destructuring to log${date}: ${description}for each expense in the array.
const { prop = default } = objassigns the default ifpropisundefined.- Defaults only apply for
undefined, notnull,0, or''. const { prop: newName } = objrenames the variable —propis not declared, onlynewName.- Combine both:
const { prop: newName = default } = obj. - Works in function parameters, loop variable declarations, and everywhere else destructuring is valid.