DEV Community

Cover image for Extract Functions Arguments using Destructure in JavaScript
Samantha Ming
Samantha Ming

Posted on • Originally published at samanthaming.com

Extract Functions Arguments using Destructure in JavaScript

Alt Text

Extract Functions Arguments using Destructure in JavaScript

ES6 Destructuring is terrific at extracting value from your arguments. So the next time you see the array bracket notation, just swap them out and use the destructuring syntax instead ๐ŸŽ‰

function omelette(...args) {
  // โŒ Old Way
  const egg = args[0];
  const cheese = args[1];

  // โœ… Better Way with Destructuring
  const [egg, cheese] = args;
}

omelette('๐Ÿฅš', '๐Ÿง€');

Breaking down the code

The first thing weโ€™re doing is collecting all our arguments into an array.

// Step 1:
(...args)

args // [ '๐Ÿฅš', '๐Ÿง€' ]

Next, weโ€™re assigning them to our variables using array destructuring.

// Step 2:
const [egg, cheese] = args;

egg; // '๐Ÿฅš'
cheese; // '๐Ÿง€'

Understanding the arguments Object

There's been some confusion on the syntax. I think it's because of the arguments objects. So I'm going to try to explain it. In every function, there is a built-in arguments object. The arguments object is an Array-like object that corresponds to the arguments passed into a function.

function omelette() {
  console.log(arguments); // { 0: '๐Ÿฅš', 1: '๐Ÿง€' }
}

omelette('๐Ÿฅš', '๐Ÿง€');

โ˜๏ธAs you can see the arguments is not an array. It is an Array-like object. To convert this into a real array, I can use the ... spread syntax.

function omelette() {
  var args = [...arguments];
  console.log(args); // [ '๐Ÿฅš', '๐Ÿง€'  ]
}

omelette('๐Ÿฅš', '๐Ÿง€');

Notice my function is NOT accepting any parameters, yet my arguments object exists. I know it's confusing cause I named it args. So let's make it crystal clear and check out a function that is passing in a parameter vs the arguments object.

function food(egg) {
  egg; // '๐Ÿฅš'
  arguments; // { 0: '๐Ÿฅš', 1: '๐Ÿš•' }
}

food('๐Ÿฅš', '๐Ÿš•');

The term Parameter vs Argument

I always thought these terms were interchangeable. Then I realize there is a language difference.

Parameter: is the variable in the function declaration. It is part of the function signature when you create it.

To use in a sentence, I'd say: "This function is accepting the name parameter"

function sayHi(name) {
  // ๐Ÿ‘ˆ parameter
}

Argument: is the actual value of the variable being passed to the function when it is called.

To use in a sentence, I'd say: "I'm passing samantha in this function"

sayHi('samantha'); // ๐Ÿ‘ˆ argument

Here's how I remember it. The "P" in Parameter stands for the Placeholder in the function declaration. The "A" in Argument stands for the the Actual value of the function.

Rest Parameters vs Arguments object

Let's start by explaining what are Rest Parameters:

The rest parameter syntax allows us to represent an indefinite number of arguments as an array.

MDN Web Docs

Rest Parameters collects individual arguments that you pass into a function and returns an array

function cook(...ingredients) { // ๐Ÿ‘ˆ Have to accept the parameters
  return ingredients;
  // [ '๐Ÿงˆ', '๐Ÿฅ“' ] ๐Ÿ‘ˆ Returns an array
}

cook('๐Ÿงˆ', '๐Ÿฅ“'); // ๐Ÿ‘ˆ Passing the arguments

However, this is different from the arguments object. Notice I didn't have to pass the arguments in the parameters. Every non-arrow function created in JavaScript has a local arguments object. It's also the reason, why you don't want to name using arguments because you will overwrite it.

function cook() { // ๐Ÿ‘ˆ NOT accepting any parameters
  return arguments;
  // { '0': '๐Ÿงˆ', '1': '๐Ÿฅ“' } ๐Ÿ‘ˆ Returns an "arguments" object
}

cook('๐Ÿงˆ', '๐Ÿฅ“'); // ๐Ÿ‘ˆ Passing the arguments

The best practice is to avoid the arguments object, instead you should use the rest parameters. It's the reason why ES6 introduced the Rest Parameters to make it easier for JavaScript developers that need to access and make it easier to work with an indefinite number of arguments ๐Ÿ‘

Arguments best practices

There are some best practices of using Function Arguments that was indicated from AirBnb's JavaScript Style Guide:

Never name a parameter arguments. This will take precedence over the arguments object that is given to every function scope.

// bad
function foo(name, options, arguments) {
  // ...
}

// good
function foo(name, options, args) {
  // ...
}

Never use arguments, opt to use rest syntax ... instead

Why? ... is explicit about which arguments you want pulled. Plus, rest arguments are a real Array, and not merely Array-like like arguments.

// bad
function foo() {
  const args = Array.prototype.slice.call(arguments);
}

// good
function foo(...args) {
}

Community Input

Setting Default Value

@lukeshiru: You can even set default values in the header.

function omelette(...[egg = '๐Ÿณ', cheese = '๐Ÿฎ']) {
  egg; // '๐Ÿณ'
  cheese; // '๐Ÿฎ'
}

omelette(); // ๐Ÿ‘ˆ NOT passing any value

Destructuring Rest Parameters

@lukeshiru: You can also do it like this.

function omelette(...[egg, cheese]) {
  egg; // '๐Ÿฅš'
  cheese; // '๐Ÿง€'
}

omelette('๐Ÿฅš', '๐Ÿง€');

โ˜๏ธ Let me just break down what @lukeshiru is doing here cause it might look at bit funky at first glance. This is the same as doing this:

// Step 1: using the rest parameter to collect the arguments
function omelette(...args) {
  args; // ['๐Ÿฅš', '๐Ÿง€']

  // Step 2: extract the value using destructuring
  const [egg, cheese] = args;
}

I did the above in 2 steps, but I could also combine all the steps into one:

// "..." --> reflects the rest parameter
// "[egg, cheese]" --> reflects the destructuring
function omelette(...[egg, cheese]) {
  egg; // '๐Ÿฅš'
  cheese; // '๐Ÿง€'
}

Resources


Thanks for reading โค
Say Hello! Instagram | Twitter | SamanthaMing.com

Top comments (10)

Collapse
 
nombrekeff profile image
Keff

Nice read!
Really well explained, I tend to use objects for this purpose, so the user sees the parameter names on the function call, but this is a great approach as well, even better if using arguments.

Collapse
 
samanthaming profile image
Samantha Ming

Thanks Manolo! And glad you found it helpful!

Totally, passing object is super cool! which kinda acts like named parameters where you don't have to worry about the order. I believe this is what you're referring to:

// Boo, arguments must be in specific order
function meal(protein, carb, veggie){
}
meal('๐Ÿฅฉ', '๐Ÿš', '๐Ÿฅฆ')


// Yay, arguments can be in any order
function meal2({protein, carb, veggie}){
}
meal2({carb: '๐Ÿš', veggie: '๐Ÿฅฆ', protein: '๐Ÿฅฉ'})

I have a tidbit on it as well > samanthaming.com/tidbits/18-named-... ๐Ÿ˜Š

Collapse
 
nombrekeff profile image
Keff

Yup that was exactly it :) I'll check it out

Collapse
 
nombrekeff profile image
Keff

For 2 arguments it is kinda not needed, although when passing in a bunch of arguments it is cleaner to do it this way.

If I have to pass a lot of parameters I tend to use with objects instead:

function omelette({ egg, ingredient }) {}

omelette({ egg:  '๐Ÿฅš', ingredient: '๐Ÿง€' });
 
nombrekeff profile image
Keff

I have to agree with you in this sense, I guess the point of the post was to not use arg[0] to access arguments and to show and explain how destructuring works. But in the example you show, it is kinda redundant. I think this will confuse more people than not.

This is why I use objects instead, at least you give some useful feature to the user (named parameters).
This: fn({ name: 'bob' }).
Instead of: fn('bob').

Collapse
 
samanthaming profile image
Samantha Ming

Thanks for the question Tomasz! I just re-wrote the article to add some explanation. Hopefully, it clarified some things...if you don't mind, can you have a read (the last section) and let me know if it helps ๐ŸคžIf it doesn't, just let me know and I'll try again ๐Ÿ˜Š

 
samanthaming profile image
Samantha Ming

For sure, in this simple example, the rest+destructuring combo doesn't really make sense. I'd stick with the 2nd way for sure ๐Ÿ‘I think the community example was just showing a different way of doing things that achieve the same thing. Coding is all about communication, so we should pick the one that best facilitates that. I always enjoy seeing all the different ways because it builds up my toolbox. The best tool is always dependent on the situation. Thanks for pointing this out and allowing me to adjust my code notes ๐Ÿ™‚

Collapse
 
stevepepple profile image
Steve Pepple

Great technique!, Ad thanks the tip about default args @lukeshiru

Collapse
 
diek profile image
diek

Learned something new! Thank you :)

Collapse
 
samanthaming profile image
Samantha Ming

Awesome, glad to hear that! thanks for reading ๐Ÿ˜€