Destructuring and Spread
Unpacking a grocery bag onto the counter, and pouring two bags into one. Two small tricks you'll use every day.
By now you've written plenty of lines like these:
const name = product.name;
const price = product.price;
const stock = product.stock;It works, but it's repetitive. Modern JavaScript has a shortcut for pulling values out of arrays and objects, and a matching one for copying and combining them. You'll see both in almost every piece of modern code, so they're worth getting comfortable with.
Destructuring objects: unpacking the bag
Picture coming home with a grocery bag and putting each thing where it belongs: milk in the fridge, bread in the bread box. Destructuring unpacks an object into separate variables in one line:
const product = { name: 'Sourdough', price: 8, stock: 12 };
const { name, price } = product;
console.log(name); // 'Sourdough'
console.log(price); // 8The curly braces on the left side of the = aren't making an object. They're saying "reach into this object and pull out these properties, into variables with the same names." Anything you don't ask for, like stock, simply stays in the bag.
Renaming and defaults
Sometimes the property name isn't the variable name you want, or the property might be missing:
const { name: breadName, isVegan = false } = product;
console.log(breadName); // 'Sourdough'
console.log(isVegan); // false: the default, since product has no isVeganname: breadNamemeans "takename, but call my variablebreadName." (The colon reads as "into.")isVegan = falsesets a default, used only when the property is missing, just like the default parameters from Functions.
Destructuring in function parameters
This is where destructuring really shines. When a function takes an object, it can unpack it right in the parameter list:
function describe({ name, price }) {
return `${name} costs $${price}`;
}
console.log(describe(product)); // 'Sourdough costs $8'Anyone reading the first line now sees exactly which properties the function needs.
Destructuring arrays: taking things in order
Arrays unpack by position instead of by name, using square brackets:
const topThree = ['Sourdough', 'Rye', 'Focaccia'];
const [first, second] = topThree;
console.log(first); // 'Sourdough'
console.log(second); // 'Rye'You name the variables whatever you like, since there are no keys to match. You already used this in Objects, in for (const [bread, count] of Object.entries(stock)): each entry is a two-item array, and [bread, count] unpacks it.
A neat trick that falls out of this: swapping two variables without a temporary one.
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1Spread: pouring everything out
The spread operator is three dots, ..., in front of an array or object. It means "pour out everything inside, right here."
Copying and combining arrays
const breads = ['Sourdough', 'Rye'];
const pastries = ['Croissant', 'Danish'];
const everything = [...breads, ...pastries];
// ['Sourdough', 'Rye', 'Croissant', 'Danish']
const copy = [...breads];
copy.push('Focaccia');
console.log(breads); // ['Sourdough', 'Rye']: untouchedRemember the sharing surprise from Arrays, where tuesday = monday made two labels for one carton? [...monday] is the fix: it pours the eggs into a new carton.
Copying and updating objects
Spread works on objects too, and it's the standard way to make an updated copy without changing the original:
const bread = { name: 'Sourdough', price: 8 };
const onSale = { ...bread, price: 6 };
console.log(onSale); // { name: 'Sourdough', price: 6 }
console.log(bread); // { name: 'Sourdough', price: 8 }: untouchedProperties are poured in from left to right, and a later one with the same name wins. So ...bread pours in both properties, then price: 6 overwrites the price. Order matters: { price: 6, ...bread } would end up with the original price of 8.
A spread copy is shallow
One warning. Spread copies the top layer only:
const order = { id: 1, items: ['Rye'] };
const copy = { ...order };
copy.items.push('Coffee');
console.log(order.items); // ['Rye', 'Coffee']: shared!copy is a new object, but its items property still points to the same array as the original's. Think of photocopying a folder's cover page: you have a new cover, but the papers clipped inside are still the originals. For a completely independent copy of nested data, use structuredClone(order).
Spreading into a function call
Spread can also pour an array out as separate arguments:
const prices = [8, 6, 9, 7];
console.log(Math.max(...prices)); // 9Math.max wants separate numbers, Math.max(8, 6, 9, 7), not an array. Spread does the unpacking for you.
Rest: gathering the leftovers
The same three dots do the opposite job in a different spot. When they appear where you're receiving values, like in a parameter list or on the left side of destructuring, they gather everything that's left into one array or object. That's called rest:
function orderSummary(customer, ...items) {
return `${customer} ordered ${items.length} items: ${items.join(', ')}`;
}
console.log(orderSummary('Ana', 'Rye', 'Coffee', 'Croissant'));
// 'Ana ordered 3 items: Rye, Coffee, Croissant'customer takes the first argument, and ...items scoops up all the rest into an array. It works in destructuring too:
const [winner, ...others] = ['Sourdough', 'Rye', 'Focaccia'];
// winner: 'Sourdough', others: ['Rye', 'Focaccia']
const { password, ...safeUser } = { name: 'Ana', password: 'secret123' };
// safeUser: { name: 'Ana' }That last one is a handy pattern for leaving a property out of a copy.
How to tell them apart: spread pours out (you're giving values), rest gathers up (you're receiving values). Same dots, opposite directions.
Try it
JavaScript
Console
Nothing logged yet. Anything you pass to console.log() shows up here.
Try it yourself
- Add
stockto the destructuring line and log it. Then rename it withstock: loavesLeft. - Move
price: 6to the front of theonSaleobject, before...product. What price do you get now, and why? - Write a function
describe({ name, price })that returns a sentence, and call it withproduct.
Check your understanding
Up next
You've been working with text since the first lesson. Now let's get serious about it: searching, trimming, splitting, and checking whether text matches a pattern. That's Strings and Regular Expressions.
