We all know what variables are, and there are plenty of times where we find ourselves using objects or arrays with long property names on them over, and over, and over... Wouldn't it be nice to just have a variable referring to that property without assigning fifty variables manually? Well, that's where destructuring comes in - destructuring is a way of saving values from complex data types to a variable without having to make a bunch of them by hand.
Basics of Destructuring
The basic syntax for destructuring is pretty simple, but a lot of people don't know how to use it, so let's go over a couple examples with both objects and arrays! We'll do this with the destructuring "binding" pattern, though there's also an "assignment" pattern. We can start with a basic object:
const obj = { a: 1, two: 83, banana: 'bread', } To "destructure" this object, we essentially just assign variables to it using object syntax!
// this grabs the "two" property and the "banana" property // from our object, but not our "a" property // this is great for when we need to reuse a value repeatedly, // like if you were using props in React! const { two, banana } = obj; // and then we can access our destructured values // like any other variable! console.log(two); // outputs 83 to the console console.log(banana); // outputs "bread" to the console Arrays have a similar destructuring syntax, but will assign values in order instead of by a key name, since they don't have the same kinds of keys an object does:
const arr = [1, 2, 3, 4, 5] const [a, b, c] = arr; // a = 1, b = 2, c = 3! So, those are the basics! But what if we wanted to get a bit more in-depth? Maybe we don't want to assign variables to EVERY value, but still want ongoing access to the remaining values separate from the original collection?
...Destructuring and the Spread Operator
We can actually use the spread operator with both arrays and objects to "scoop up" the remaining values into a neat little array/object separate from the original one! For arrays, the result is simple enough:
const groceries = ["spaghetti", "tomatoes", "milk", "butter", "cheese"]; const [pasta, fruit, ...dairy] = groceries; // "pasta" holds "spaghetti", // and "fruit" holds "tomatoes", just like before, // but now we have access to a "dairy" array // which looks like this: ["milk", "butter", "cheese"] Cool, right? Objects are pretty much the same, but instead save the results to a new object with the remaining properties on it:
const zeldaQuotes = { dekuScrub: "Twenty-three is number one!", link: "Hyah! Hup! Ha! Hyah!", navi: "Hey, listen!", zelda: "Help me, Link! You're my only hope! Wait, wrong franchise..." }; const { link, navi, ...rest } = zeldaQuotes; console.log(link); // outputs "Hyah! Hup! Ha! Hyah!" console.log(navi); // outputs "Hey, listen!" console.log(rest); // ^ outputs an object that looks like this: // (I shortened the quotes for space) // { dekuScrub: "...", zelda: "..." } Notice how, with objects, we don't even need to grab the properties in order! We got link and navi, skipping dekuScrub entirely, but our rest variable still has both zelda AND our skipped dekuScrub!
Well, that's cool and all, but what are some other things we can do?
More cool stuff!
Nested Destructuring and Default Values
Well, what if maybe one of our values was undefined? That's when you'd use a default value. Just like with a function parameter, you can assign a "default" to a destructured variable in case the value is undefined! This is pretty easy:
// since b's value is undefined, it's automatically set to 12 // note: would not take effect if we used null instead of undefined const { a, b = 12, c } = { a: 1, b: undefined, c: 18 }; And if a value in an array or object is another array or object, we can nest destructuring syntax to get to these nested values more quickly and conveniently:
const obj = { a: 1, b: { c: 13 }, d: 9 }; const { a, b: { c }, d } = obj; console.log(c); // outputs 13! const arr = [ 1, [ 13, 18 ], 12 ]; const [ a, [ b, c ], d ] = arr; console.log(a, b, c, d); // outputs 1 13 18 12 Reassignment
If we want to reassign destructured values, we can simply use the let keyword instead of const! If we want some values to be reassignable and others not to be, we'd have to destructure multiple times:
const obj = { a: 1, b: 2, c: 3}; const { a, b } = obj; let { c } = obj; console.log(c); // outputs 3 c = 4; console.log(c); // outputs 4! a = 2 // TypeError: Assignment to constant variable :( Variable Swapping
With arrays and simple values, you can use destructuring to easily swap values! I personally found this really helpful in a function I wrote recently.
let pop = 'tart'; let tart = 'pop'; // outputs "tartpop"... that doesn't seem quite right... console.log(pop + tart); [pop, tart] = [tart, pop]; // basic destructuring swap! console.log(pop + tart); // outputs "poptart" :D const arr = [ 1, 2, 3 ]; [arr[0], arr[1], arr[2]] = [arr[1], arr[2], arr[0]]; console.log(arr); // outputs [2, 3, 1]! Ignoring Values w/ Arrays and Function Destructuring
If you want to skip a value when destructuring an array, you can simply leave an empty space in its place:
const arr = [ 1, 2, 3 ]; const [ a, , b ]; // a = 1, b = 3, we don't need 2! Additionally, we can easily destructure function outputs, which is quite frequently used when working with React hooks! This is a bit of a silly example, but here's a basic showcase of destructuring the output of a function that returns an array:
function makeArr(...args) { return args; } [a, b, c] = makeArr(1, 2, 3); console.log(a, b, c); // outputs 1 2 3 We can even destructure function parameters if we know what kinds of arguments we'll get, which I personally use a lot with both imports and when passing values through props with React!
function logProperties({ a, b, c }) { console.log(a, b, c); } logProperties({ a: 1, b: 2, c: 3 }); // outputs 1 2 3 Wrapping up...
That's most of the stuff on destructuring I could find that'd make sense to include. Destructuring is a surprisingly in-depth topic in and of itself, and on the MDN page alone I found quite a bit of info on them that I've already started integrating into my daily code usage. It's definitely been a more fun topic to look into than I thought it would be.
Top comments (0)