Wednesday, October 9, 2024

Destructuring Mixed Objects and Function Arguments in ES6

JavaScript Examples

Object destructuring is a useful JavaScript (ECMAScript 6) feature to extract properties from objects and bind them to variables. As we saw in the ES6 Object Destructuring tutorial, object destructuring can extract multiple properties in one statement, access properties from nested objects, and can set a default value if the property does not exist. In today’s follow-up, we will be taking a look at mixed (Object and Array) destructuring, as well as how to destructure function and method arguments.

What is Mixed Destructuring in JavaScript?

As alluded to in the intro, mixed destructuring involves the declaring and setting of variables from an object that contains attributes of Arrays or from an Array of Objects. To illustrate, here’s a <b>Person Object</b> that contains nested elements of both Objects and Arrays:

const person = {
  name: 'Rob',
  location: {
    city: 'Ottawa',
    country: 'Canada',
    phoneNumbers: ['555-1234', '555-2345'],
  },
};

We can then employ ES6 Destructuring to assign all object properties to individual variables by replicating the object structure:

const {
  name,
  location: {
    city,
    country,
    phoneNums: [phone1, phone2],
  },
} = person;

// Now we can reference each variable without having to use dot (.) attribute accessors.
// Outputs "I am Rob from Ottawa, Canada. You can reach me at 555-1234 or 555-2345."
console.log(
  `I am ${name} from ${city}, ${country}. You can reach me at ${phone1} or ${phone2}.`
);

We can also use ES6 Destructuring to assign Array elements to individual variables, as long as we know the array’s length before-hand. Here is an example that shows how it is done:

const dataArray = [
  { data: 1 },
  { data: 2 },
  { data: 3 }
];

const [
  { data: val0 },
  { data: val1 },
  { data: val2 }
] = dataArray;

//Outputs "1, 2, 3"
console.log(`${val0}, ${val1}, ${val2}`);

The trick is to replace the element values with variables in which to store them.

Read: A guide to Working with CSS Variables

Destructuring Object Function Arguments in JavaScript

Objects passed to functions can be destructured within the function signature where function arguments are defined. This time, we would replicate the object structure in the arguments list:

//Programmer Object containing nested elements
const programmer = {
  name: 'George',
  age: 29,
  skills: {
    languages: 'JavaScript, HTML, CSS',
    databases: 'MySQL, MS SQL, MongoDB',
  },
};

//The programmer object is destructured within the parameters of the function that is passed in
const displayEmployeeInfo = ({ name, age, skills: { languages, databases } }) => {
  console.log(
    `The employee name is ${name} and his age is ${age}. 
		 He knows the following languages - ${languages} 
		 and is familiar with the databases - ${databases}.`
  );
}

//Invoke the displayEmployeeInfo() function with the programmer object
//Output: The employee name is George and his age is 29. He knows the following 
//languages - JavaScript, HTML, CSS and is familiar with the databases - MySQL, 
//MS SQL, MongoDB 
displayEmployeeInfo(programmer); 

Destructured Parameters and Default Values

Like any function parameters, we can assign default values to our local variables right in the function signature. Here is the displayEmployeeInfo() function again with default values assigned to the skills, languages and database variables:

//Programmer Object without skills
const programmer = {
  name: 'George',
  age: 29,
  skills: {
    languages: 'JavaScript, HTML, CSS'
  }
};

const displayEmployeeInfo = ({ name, age, skills: { languages = 'none', databases = 'none' } }) => {
  console.log(
    `The employee name is ${name} and his age is ${age}. 
     He knows the following languages - ${languages} 
     and is familiar with the databases - ${databases}.`
  );
}

//Invoke the displayEmployeeInfo() function with the programmer object
//Output: The employee name is George and his age is 29. He knows the following 
//languages - JavaScript, HTML, CSS and is familiar with the databases - none
displayEmployeeInfo(programmer); 

Making Destructured Parameters Optional

Note that, even though we have specified default values for some of the variables, if we were to call the displayEmployeeInfo() function with no arguments we would get an error because destructured parameters are always required.

const displayEmployeeInfo = ({ name, age, skills: { languages = 'none', databases = 'none' } }) => {
  console.log(
    `The employee name is ${name} and his age is ${age}. 
     He knows the following languages - ${languages} 
     and is familiar with the databases - ${databases}.`
  );
}

//Invoking the displayEmployeeInfo() function with no arguments
//throws the Error "TypeError: (destructured parameter) is undefined"
displayEmployeeInfo(); 

The key to avoiding the above error is to assign a fallback object literal for all higher-level objects, including the programmer object and the nested skills object.

const displayEmployeeInfo = ({ name = "John Doe", age = "unknown", skills: { languages = 'none', databases = 'none' } = {} } = {}) => {
  document.write(
    `The employee name is ${name} and his age is ${age}. 
    He knows the following languages - ${languages} 
    and is familiar with the databases - ${databases}.`
  );
}

//Invoking the function displayEmployeeInfo with the programmer object
//Output: The employee name is John Doe and his age is unknown. He knows the following 
//languages - none and is familiar with the databases - none
displayEmployeeInfo(); 

Final Thoughts on Destructuring Mixed Objects and Function Arguments in ES6

In this web development tutorial, we explored a couple of the more advanced applications of ES6 destructuring syntax. As powerful as destructuring is on its own, they are capable of streamlining your code even further when combined with other ES6 features such Spread Syntax and Rest Parameters.

You will find a demo of today’s code examples on codepen.io. There, you can look over the code and observer the output produced.

Read: Project Management Tools for Web Developers

Rob Gravelle
Rob Gravelle
Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Popular Articles

Featured