DEV Community

Cover image for JS 101: Destructuring Assignment over Function Parameters
Kris Guzman
Kris Guzman

Posted on

JS 101: Destructuring Assignment over Function Parameters

JavaScript: Use Destructuring Assignment over Function Parameters

With ES6 comes the ability to leverage destructuring assignment. For those who aren’t familiar with the syntax, it can seem a little weird. Once you understand how it works, I promise you will want to use it almost everywhere.

Quick Primer on Destructuring Assignment

Destructuring assignment with objects is just a way to take any JavaScript object:

const myFoods = {a: 'apple', b: 'banana', c: 'carrot', d: 'donut'}
Enter fullscreen mode Exit fullscreen mode

And pull out the parameters we want into its own variable:

const { a, b, c, d} = myFoods
Enter fullscreen mode Exit fullscreen mode

If we aren’t sure a variable exists, we can easily provide a default value:

const {a = 'apple didn't exist', b, c, d} = myFoods
Enter fullscreen mode Exit fullscreen mode

If we want to rename one of the variables, we can do so like this:

// we renamed a to be apple 
const {a: apple, b, c, d} = myFoods
Enter fullscreen mode Exit fullscreen mode

If we only want fruits (a and b without c and d), we can pick out the fruits and group the random foods by doing the following:

// you will often see "...rest" used as a convention 
const {a, b, ...otherFoods} = myFoods  
const carrotAndDonut = {...otherFoods} 

console.log(carrotAndDonut) // prints out {c: 'carrot', d: 'donut'}
Enter fullscreen mode Exit fullscreen mode

And that’s all there really is to it!

How this will replace your function parameters

Lets say we have the following function:

function printFruits(apple, banana) {
    console.log(`we should have an ${apple} and ${banana}`)
}
Enter fullscreen mode Exit fullscreen mode

Okay great, we expect an apple and banana. Let’s say we are using the same object as the one demonstrated in the primer:

const myFoods = {a: 'apple', b: 'banana', c: 'carrot', d: 'donut'}
Enter fullscreen mode Exit fullscreen mode

We can use printFruits as follows:

// a corresponds to apple, b corresponds to banana
printFruits(myFoods.a, myFoods.b)
Enter fullscreen mode Exit fullscreen mode

But there are a few problems here

First, order of parameters matters. The following can happen very easily and cause hard to track bugs:

// an innocent swap of variables can rain hell on our software
printFruits(myFoods.b, myFoods.a)
Enter fullscreen mode Exit fullscreen mode

Also, what if we want printFruits to be smart enough to extract the fruits it expects and discard everything else? We could do the following using the ...rest syntax in ES6 (yes, it works for function parameters too):

function printFruits(apple, banana, ...otherFruits) {
    console.log(`we should have an ${apple} and ${banana}`)
}
Enter fullscreen mode Exit fullscreen mode

But now we have an unused variable, which is yucky.

Okay, no problem, what if we just passed in the whole object like below:

function printFruits(myFoods) {
    console.log(`we should have an ${myFoods.a} and ${myFoods.b}`)
}

printFruits(myFoods)
Enter fullscreen mode Exit fullscreen mode

That’s a little better. It solves the problems above, but introduces a new one by losing the clarity of the function signature. Before, we knew immediately that we needed to pass an apple and banana. Now we have to actually look at the function definition to see what we are trying to grab out of myFoods. Not so fun when your function spans 100 lines.

This is where destructuring assignments really shines. Here is what printFruits looks like using destructuring assignment:

function printFruits(myFoods) {
    const {a, b} = myFoods
    console.log(`we should have an ${a} and ${b}`)
}

printFruits(myFoods)
Enter fullscreen mode Exit fullscreen mode

We can go one step further and actually use destructuring assignments right in the function’s parameters:

function printFruits({a, b}) {
    console.log(`we should have an ${a} and ${b}`)
}

printFruits(myFoods)
Enter fullscreen mode Exit fullscreen mode

And if we don’t like the (purposefully vague) parameter names, we can always rename them!

function printFruits({a: apple, b: banana}) {
    console.log(`we should have an ${apple} and ${banana}`)
}

printFruits(myFoods)
Enter fullscreen mode Exit fullscreen mode

As well as give a default value if we try to pull out a variable that doesn’t exist:

function printFruits({a: apple = 'default apple', b: banana = 'default banana'}) {
    console.log(`we should have an ${apple} and ${banana}`)
}

printFruits(myFoods)
Enter fullscreen mode Exit fullscreen mode

If I’m using Flow or TypeScript, who cares?

Fair, but using this method (pun not intended) you can still free yourself from worrying about the order of parameters. Even in TypeScript, if you have two parameters that are both strings, you may accidentally swap them and be in an even worse position than non Flow / TypeScript folks because you trusted the system to catch that for you.

That being said, this is primarily for my vanilla JS folks out there who want a little more safety in their code. We shouldn’t let a type system keep us from doing our due diligence as not every project we come across as developers will make use of Flow or TypeScript.

Final Thoughts

I hope this helps shine some light on the practical benefits on destructuring assignment in JavaScript. There are plenty more applications, but this one I found to be one of the most common. Let me know your thoughts in the comments section!

Top comments (1)

Collapse
 
quamelincoln profile image
quamelincoln

like it