Structure
trashhand at Pexels

What is Destructuring?

At its core, destructuring is the idea that we are pulling out values individually from a previously-created object or array. Mozilla Developer Network (MDN) defines destructuring as a feature in JavaScript that “makes it possible to unpack values from arrays, or properties from objects, into distinct variables.”

Here’s an example of the two types of destructuring we’re discussing in this article:

// Array destructuring
const arrayOfNumbers = [1, 2, 3, 4, 5];
const [one, two, three, four, five] = arrayOfNumbers;

// Object destructuring
const objectOfNumbers = { one: 1, two: 2, three: 3, four: 4, five: 5 };
const { one, two, three, four, five } = objectOfNumbers;

If you haven’t ever seen or used destructuring before, the code above probably looked a little weird. The first example shows an array, called arrayOfNumbers. On the next line, we’ve switched the positions of the arrayOfNumbers variable name and the [1, 2, 3, 4, 5] array assignment. They’ve now been assigned to variable names in the array that looks like [one, two, three, four, five].

This is destructuring, and we’ll get into its use cases and the philosophy behind it shortly. For now, just get a feel for the syntax. Also, notice the next example of object destructuring (with code below so you don’t have to scroll up). We start with a variable called objectOfNumbers, and we assign an object with key-value pairs to it:

// Object destructuring
const objectOfNumbers = { one: 1, two: 2, three: 3, four: 4, five: 5 };
const { one, two, three, four, five } = objectOfNumbers;

We switch up the syntax for the next line of destructuring. However, this one has a twist; we’re missing the value for the key-value pairs of one: 1, two: 2, etc.

We’ll talk about that more in a second.

Array Destructuring: Fluid and Adaptable

The first form of destructuring is done through the use of arrays. Here’s a very simple block of code that we’re going to be working through:

function outerFunction() {
  function firstFunction() {
    return 1;
  }
  function secondFunction() {
    return 2;
  }
  function thirdFunction() {
    return 3;
  }
  return [firstFunction, secondFunction, thirdFunction];
}

const [first, second, third] = outerFunction();

Notice that we have a main function, outerFunction, which has three inner functions inside of it; also, outerFunction returns these three functions within an array when we call it.

This is possible because functions are “first-class citizens” in JavaScript, which is just an overly complicated way of saying that they can be passed around as values or returned from a function just like any other value!

Finally, notice how we have this line of code underneath our outerFunction function:

const [first, second, third] = outerFunction();

Neat! Now, there are a few things that I want to emphasize about this line of code:

  1. First off, this is what destructuring is!
  2. The lefthand side of “the assignment operator” (an overly complicated way to say “the equal sign”) is pulling out each of the functions returned in the array
  3. When we pull them out like this, the functions are referenced by their index (this will make sense in a minute, so don’t stress if it doesn’t now)

We are pulling out each of the three functions individually so that we don’t have to reference them like this:

const functionsArray = outerFunction();

const first = functionsArray[0]; // References the first function
const second = functionsArray[1]; // References the second function
const third = functionsArray[2]; // References the third function

first(); // Returns 1
second(); // Returns 2
third(); // Returns 3

While this works, it’s messy. In the first code block of this section, we pulled out each of the three functions with destructuring. After that, we can merely invoke the function like this:

const [first, second, third] = outerFunction();

first(); // Returns 1

Array destructuring also allows us to manipulate the variable names of what we’re destructuring out. We could just as easily have renamed our functions to something completely random:

const [banana, orange, grapefruit] = outerFunction();

banana(); // Returns 1
orange(); // Returns 2
grapefruit(); // Returns 3

The reason their names don’t matter when we use array destructuring to access them is that, in an array, destructuring is based on the index of the value and not the name.

The drawback to this is that, if we only wanted the second array position value while destructuring, we’d have to write this:

const [, orange] = outerFunction();

// We have to put the comma in since we need to signify that we're
// choosing "orange" (the second array position)

Because array destructuring is based on the index, we can use this to our advantage sometimes by renaming what we’re destructuring out.

For instance, here’s an example of the useState hook in React where we call it multiple times and rename the values we’re destructuring:

import React, { useState } from "react";

function Button(props) {
  const [colorState, setColorState] = useState("red");
  const [textState, setTextState] = useState("Click me");

  function handleClick(e) {
    e.preventDefault();
    setColorState("blue");
    setTextState("Thanks!");
  }

  return (
    <button style={{ color: colorState }} onClick={handleClick}>
      {textState}
    </button>
  );
}

If you don’t know React or React Hooks, don’t stress; the important thing to take away from this code snippet is that we’re using the exact same function (useState) twice, but we’re using different names for the destructured values so we don’t get any errors from multiple variables with the same name. This is why array destructuring is so powerful!

With that out of the way, let’s look at the other form of destructuring…

Object Destructuring: Named and Precise

If arrays are the dynamic rubber stamps of the destructuring world, objects are surgical and precise.

With array destructuring, the order you that pull values out matters since you are referencing the values based on index. But with objects, you are accessing values based on the name (the key of the key-value pairs). Here’s a code example:

const exampleObject = {
  one: 1,
  two: 2,
  three: 3
};

const { one, two, three } = exampleObject;

console.log(one); // Logs 1 to the console
console.log(two); // Logs 2 to the console
console.log(three); // Logs 3 to the console

Because we’re referencing the key-value pairs inside the object based on name (and not index), we could write our code like this:

const { three, two, one } = exampleObject;

console.log(three); // Returns 3
console.log(two); // Returns 2
console.log(one); // Returns 1

While the order we’re listing the items in is completely different, the outcome is exactly the same. Each of these key names still references the same value inside the object.

For instance, we can pull the two key-value pair out of the object like this:

const { two } = exampleObject;

console.log(two); // Logs 2 to the console

This is perfect for accessing exactly what we want inside an object (and no more). However, this also means that we can’t just destructure the same value out twice right next to each other:

const { two } = exampleObject;
const { two } = exampleObject;

// This throws a SyntaxError since "two" has already been defined

We would have to do something slightly more complicated like this (by renaming two to newTwoValue):

const { two } = exampleObject;
const { two: newTwoValue } = exampleObject;

// This is fine since we're renaming "two" to "newTwoValue" in the
// second line

Now that we’ve defined how to use array and object destructuring, we can get a bit theoretical and briefly discuss when to use them.

Choosing the Right Tool for the Job

Ultimately, it’s going to be up to you to decide when to use object and array destructuring. As an engineer, you are being paid for the ability to know when and how to use certain tools.

Here’s a list of guidelines I try to follow on when to use object or array destructuring:

  1. Do you need to pull values out of a function multiple times in the same scope/file? If so, use array destructuring since you can rename them as much as you want.
  2. Do you want to be able to rename values when you destructure them out? While it’s possible with objects, it’s much cleaner using arrays.
  3. Do you need to access values passed down from a parent component in a front-end framework? If so, use object destructuring.
  4. Do you want to only pull out the values you need while destructuring (and no others)? If so, use object destructuring.

Conclusion

I hope you’ve enjoyed this article on destructuring. It’s such a powerful tool in JavaScript as it can quickly clean up your code and allow you to do all sorts of interesting things.

You should now be able to confidently walk into any interview and use this syntax to your advantage.

LEAVE A REPLY

Please enter your comment!
Please enter your name here