Back to Blog

Level Up Your JavaScript - The Power of Destructuring Explained

Encapsulation, polymorphism, and even the titular "destructuring" – the list of technical terms that can make a beginner's head spin is long. When faced with such sophisticated terminology, it's natural for any new programmer to wonder what kind of complexity lies beneath. Fortunately, it often turns out that fancy names have little to do with the actual difficulty of the underlying concept. Destructuring, now a well-established feature in JavaScript, is no exception to this rule.

What will I cover this time? Let's see:

  • What is destructuring?
  • Array destructuring
  • Object destructuring
  • Default values
  • Practical applications of destructuring

 

What is Destructuring?

As Kyle Simpson aptly put it in his book "You Don't Know JS: ES6 & Beyond" the manual assignment of an indexed value from an array or a property from an object can be called "structural assignment."

Screenshot 2024-06-28 at 11.55.28 a.m.

Okay, but what does this have to do with the mysterious "destructuring"? Following Kyle's reasoning, we can expect an operation that does the opposite of what's shown in the example above. Let's see how this works in practice.

Screenshot 2024-06-28 at 11.56.34 a.m.

At first glance, this syntax might leave a big question mark above your head. Where did the parentheses around our variable names come from? How do values get assigned to the individual variables? Where did the returned array go?

Destructuring assignment is an expression that allows you to unpack values from arrays or properties from objects into distinct variables. This is achieved by symmetrically reversing the assignment pattern. The left-hand side is treated as a pattern for decomposing values from the array/object.

Screenshot 2024-06-28 at 11.57.58 a.m.

If the pattern doesn't match a value, the variable will receive the value undefined. The object returned by the bar function doesn't have an a property, so no numerical value is assigned to it. If you're having trouble understanding how the bar function works, I invite you to read my post on arrow functions. (https://www.codesmith.io/blog/exploring-arrow-functions-in-javascript)


Alright, we're able to unpack values from objects and arrays using this new, fancy syntax. Is that all destructuring has to offer?


Array Destructuring

Now that we know the basics of the syntax, we can move on to more interesting tricks.

Screenshot 2024-06-28 at 12.00.42 p.m.

If we want to skip a specific element, we put a comma in its place. This allows us to selectively unpack the elements of the returned array.

If we want to assign a few elements and gather the rest of the array into a separate variable, we can use the spread syntax(...).

Screenshot 2024-06-28 at 12.02.26 p.m.

If there are no remaining elements in the array to be gathered by the spread syntax, the variable assigned with the spread syntax will become an empty array.

Screenshot 2024-06-28 at 12.03.05 p.m.

It turns out that array destructuring uses an iterator to access the source values. This means we can use this syntax for any iterable value. Besides arrays, this includes strings, maps, sets, and structures returned by DOM operations.

Screenshot 2024-06-28 at 12.19.27 p.m.

 

Failed Array Destructuring

If we use array syntax like const  [a, b], and try to assign from a source that isn't iterable, the engine will throw a TypeError.

Screenshot 2024-06-28 at 12.20.47 p.m.

If we're not 100% sure about the values being processed by destructuring (e.g., asynchronous functions), we need to be extra careful.

 

Object Destructuring

To destructure an object, we can use curly braces {} to create a pattern that mirrors the structure of the object you want to extract values from. Inside the curly braces, we list the properties we want to extract, using their original property names as variable names.

There's nothing stopping us from using variable names that differ from the property names of the object we're destructuring. However, this involves using syntax that might seem a bit convoluted at first.

Screenshot 2024-07-03 at 1.35.11 p.m.

The world is upside down, everything is reversed! As you can see, on the left-hand side, we're dealing with the pattern source -> target. Traditional assignment uses the pattern target <- source. Don't panic, as is often the case in programming, after working through a few examples, everything will fall into place.

Destructuring allows us to use computed property keys. This refers to property names calculated from the value of a variable, which is possible with a bracket notation [].

Screenshot 2024-07-03 at 1.36.20 p.m.

 

Failed Object Destructuring

When destructuring primitive values (like numbers, strings, or booleans), JavaScript temporarily converts these values to their corresponding object wrappers to access their properties. This means that destructuring will generally work as expected for these primitives. However, destructuring will fail when trying to access properties on null or undefined  values, as these values have no corresponding object wrappers.

Screenshot 2024-07-03 at 1.38.11 p.m.

Additionally, if we start our statement with curly braces, the engine will interpret them as defining the boundaries of a block. To use destructuring, it's worth sticking to variable initialization. If we're interested in assignment, we can use the workaround with parentheses.

Screenshot 2024-07-03 at 1.39.28 p.m.

 

Default Values

In case of a mismatch between the source value, destructuring allows for optional functionality. We can protect against assigning undefined to a variable by defining a default value.

Screenshot 2024-07-03 at 1.40.08 p.m.

Interestingly, the default value can refer to a variable from the same pattern.

Screenshot 2024-07-03 at 1.40.47 p.m.

Of course, it's important to remember that the default value will only be calculated if needed. The value matched from the source takes precedence.

Screenshot 2024-07-03 at 1.41.30 p.m.

 

Practical Applications of Destructuring

We've managed to gather quite a bit of new syntax. Let's see how this translates into our problem-solving skills.

Destructuring arrays returned by methods

JavaScript has a dozen built-in methods that return arrays. Often, we care about specific elements, not the array itself. A good example begging for destructuring is String.prototype.split()

Screenshot 2024-07-03 at 2.00.51 p.m.

Importing Specific Functionality

Destructuring can be a powerful tool when importing specific functions or variables from a module. Instead of importing an entire module, we can import only the parts we need. Here’s an example of how to use destructuring with CommonJS to import specific functions from a module:

Screenshot 2024-07-03 at 2.01.46 p.m.

For instance, if we have a module named utility-functions that exports multiple functions, but we only need calculateSum and findMax, we can import just those.

Screenshot 2024-07-03 at 2.03.04 p.m.

This way, we can keep our code cleaner and only include the functionality we need from external modules.


Swapping Values

Swapping values traditionally requires a temporary variable, which can make the code less elegant. However, with destructuring, we can achieve this more cleanly and concisely.

Screenshot 2024-07-03 at 3.52.05 p.m.

 
Parameter Destructuring

I saved the best for last. Many of the functions we write take an object as a parameter. Typically, we need to check if the parameter is undefined and then set default values for each property before moving on to the actual function logic. This results in a lot of code lines with little benefit. Fortunately, destructuring greatly improves our situation.

Screenshot 2024-07-03 at 3.53.38 p.m.

With destructuring, we can directly unpack and assign default values to object properties within the function's parameter list. This eliminates the need for those repetitive checks and assignments, resulting in more concise and readable functions.


Summary

Destructuring offers an elegant way to work with data in JavaScript, whether it's pulling values from arrays, objects, or even function arguments. By taking advantage of this feature, you'll write cleaner, more maintainable code that's ready for the challenges of modern JavaScript development. And this is just the beginning – as you explore more advanced JavaScript concepts (and libraries like React), you'll find that destructuring becomes an invaluable part of your toolkit.

The MDN documentation on destructuring: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment