DEV Community

Cover image for JavaScript object destructuring tips
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

JavaScript object destructuring tips

Regarding JavaScript, we get an extremely useful way of extracting properties from objects.

Note: Destructuring also works on arrays, but let's focus on objects for this one

Let's say we have a user object and want to extract the properties of individual variables.

const user = {
  name: 'Chris',
  age: 33,
};
Enter fullscreen mode Exit fullscreen mode

Before ES2015, we would have to assign these variables by explicitly assigning them like so:

var name = user.name;
Enter fullscreen mode Exit fullscreen mode

This still works in modern JavaScript. However, it can be optimized.
We can omit the double use binding of the name properties and destructure the properties like this.

const { name, age } = user;

console.log(name);
// Chris

console.log(age);
// 33
Enter fullscreen mode Exit fullscreen mode

Wait, what?
Pretty much magic, right? We don't have to double name the variables and can assign them directly to their variables.

Destructure and keep a rest object

Let's say you have an object with multiple fields. You want to extract one of the fields and keep track of whatever is left.

You might think we need to assign all the remaining properties, but this is built-in by using the spread operator.

const user = {
  name: 'Chris',
  age: 33,
  username: 'DailyDevTips',
};

const { name, ...rest } = user;

console.log(name);
// Chris

console.log(rest);
// { age: 33, username: 'DailyDevTips' }
Enter fullscreen mode Exit fullscreen mode

Destructure nested object properties

Quite often, your object will have multiple layers.
With destructuring, we can also target nested properties.

const user = {
  name: 'Chris',
  age: 33,
  username: 'DailyDevTips',
  address: {
    country: 'South Africa',
    postalCode: '7700',
  },
};
Enter fullscreen mode Exit fullscreen mode

Let's take the above example. How can we extract the country in one go?

const {
  address: { country },
} = user;

console.log(country);
// South Africa
Enter fullscreen mode Exit fullscreen mode

But what happens if we want to extract the whole address object and the country?

In the above example, if we try to log address it will state: ReferenceError: address is not defined.

However we can simply pass another reference in the destructuring like this:

const {
  address: { country },
  address,
} = user;

console.log(address);
// { country: 'South Africa', postalCode: '7700' }

console.log(country);
// South Africa
Enter fullscreen mode Exit fullscreen mode

Destructure with a different name

Perhaps you want to destructure some properties under a different name.

Let's take the example above and state that we want to receive the address object named shippingAddress.

We can use the semicolon : divider to address a new name.

const { address: shippingAddress } = user;

console.log(shippingAddress);
// { country: 'South Africa', postalCode: '7700' }
Enter fullscreen mode Exit fullscreen mode

This is a great way to create variables that you can directly use.

Destructure potentially empty values

Let's retake our user object, we already destructured the age, but I forgot to mention this is an optional parameter.

Some users might have chosen not to set it. In that case, we can fall back on a default value.

Note: This is a bit weird for the age property, so see this as an example

const user = {
  name: 'Chris',
  age: 33,
};

const { age } = user;

console.log(age);
// 33
Enter fullscreen mode Exit fullscreen mode

That works great, but let's see a user that doesn't have the age property.

const user = {
  name: 'Yaatree',
};

const { age } = user;

console.log(age);
// undefined
Enter fullscreen mode Exit fullscreen mode

We can destructure it with a value if we want to set a default age.

const { age = 25 } = user;

console.log(age);
// 25
Enter fullscreen mode Exit fullscreen mode

Destructure inside a loop

All the above examples work based on flat objects, but a lot of the time, you'll have an array of users.

const users = [
  {
    name: 'Chris',
    age: 33,
  },
  {
    name: 'Yaatree',
    age: 2,
  },
];
Enter fullscreen mode Exit fullscreen mode

We can loop over these items and destructure them inside the loop.

for (let { name, age } of users) {
  console.log(`User: ${name} is ${age} years old πŸŽ‰`);
}

// 'User: Chris is 33 years old πŸŽ‰'
// 'User: Yaatree is 2 years old πŸŽ‰'
Enter fullscreen mode Exit fullscreen mode

Dynamic name destructuring

What happens when we only know the variable we want to destructure at runtime?

Let's say a user clicks a button that allows them to extract a random property from the object.

The handler would have the following property.

const getProperty = 'name'; // or 'age'

// How do we get this from the user now?
Enter fullscreen mode Exit fullscreen mode

To use this, we can use the square bracket annotation.

const { [getProperty]: returnValue } = user;

console.log(returnValue);
// Chris
Enter fullscreen mode Exit fullscreen mode

Destructure from a function

Let's say we have a function that returns an object.

const getProduct = () => {
  return {
    id: 1,
    name: 'Macbook',
  };
};
Enter fullscreen mode Exit fullscreen mode

If we call it by default, it will look like this.

const product = getProduct();

console.log(product);
// { id: 1, name: 'Macbook' }
Enter fullscreen mode Exit fullscreen mode

However, we only want the id from this function. Can we do that?

const { id } = getProduct();

console.log(id);
// 1
Enter fullscreen mode Exit fullscreen mode

Yes, we can. We can simply destructure the return value and assign the property we need.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (23)

Collapse
 
peerreynders profile image
peerreynders • Edited

… and destructuring can be used directly in the parameter list

function grade({ score }) {
  if (score >= 90) return 'A';
  if (score >= 80) return 'B';
  if (score >= 70) return 'C';
  if (score >= 60) return 'D';
  return 'F';
}

console.log(
  [
    { name: 'a', score: 91 },
    { name: 'b', score: 80 },
    { name: 'c', score: 79 },
    { name: 'd', score: 60 },
    { name: 'f', score: 59 },
  ].map(grade)
); // ["A", "B", "C", "D", "F"]
Enter fullscreen mode Exit fullscreen mode

Using the rest property to omit properties

const {b, c, ...redacted} = {a: 4, b: 'top', c: 'secret', d: 1};
console.log(redacted); // {a: 4, d: 1}
Enter fullscreen mode Exit fullscreen mode

Sadly Pattern Matching didn't make any progress at the 91st TC39 meeting.

How is this related?

"Pattern matching is a conditional construct and destructuring isn’t" [ref]

i.e. Pattern matching is destructuring on steroids.

const res = await fetch(jsonService)
match (res) {
  when ({ status: 200, headers: { 'Content-Length': s } }):
    console.log(`size is ${s}`);
  when ({ status: 404 }):
    console.log('JSON not found');
  when ({ status }) if (status >= 400): do {
    throw new RequestError(res);
  }
};
Enter fullscreen mode Exit fullscreen mode

Library-based example

(I always hate how switch is a statement and not an expression always forcing me to do the switch/case/return thing)

Collapse
 
artydev profile image
artydev

Great thank you

Collapse
 
bobgravity1 profile image
bobgravity1

this type of destructing is particularly useful for frameworks like Gatsby. It becomes a nightmare pulling data from GraphQL data layers. This stuff changed my skill level big-time. Glad someone covered it so in depth for those who don't know how to use it at this level

Collapse
 
dailydevtips1 profile image
Chris Bongers

Always happy to share πŸ’–

Collapse
 
elsyng profile image
Ellis • Edited

Destructure potentially empty objects
and avoid a js runtime error:

const { age } = user || {};
Enter fullscreen mode Exit fullscreen mode

(unless someone has a better idea.)

Collapse
 
sadid369 profile image
Sadid

game changing for me. Thanks a lot. Love From Bangladesh πŸ‡§πŸ‡©

Collapse
 
lisacee profile image
Lisa Cee

A really great summary.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thanks a lot Lisa πŸ’–

Collapse
 
murdej profile image
murdej

Thank, I'm a bit smarter againπŸ˜€

Collapse
 
dailydevtips1 profile image
Chris Bongers

Keep learning little bits every single day πŸ’–

Collapse
 
andrewbaisden profile image
Andrew Baisden

Good snippets thanks for putting them together.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Glad you enjoyed them Andrew πŸ’–

Collapse
 
mjcoder profile image
Mohammad Javed

Another very good JS article. Keep them coming. πŸ‘πŸ’―

Collapse
 
dailydevtips1 profile image
Chris Bongers

Glad you are enjoying them πŸ’–

Collapse
 
dsmark profile image
Sanskar Sahu

Such a nice article you dude.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thanks a lot Sanskar πŸ’–

Collapse
 
artydev profile image
artydev

As usual, very useful, Thnaks Chris :-)

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thanks a lot πŸ’–