Javascript: Destructuring Objects (K-Pop Edition)

In this post I’ll be explaining how destructuring objects work in JavaScript, using the Feynman technique and K-pop groups. For destructuring arrays, check out my “JavaScript: Destructuring Arrays (80’s & 90’s Boy Bands Edition” post.

This is part of the Feynman Technique/20 hr Method challenge. For more information, click here.

Refresher

Destructuring is when you take an element out of a group (whether within an array or an object) and allow it to be pulled on its own. Like ordering a happy meal from McDonald’s, but just wanting the toy.

With destructuring, many of the rules are the same for both arrays and objects. However, with objects, there’s no need for “skips” and the order of calling these items does not matter.

Base Code:

All examples (for the exception of the very last sample) will use the following as it’s foundation code:

const kpop = {
  superJunior: [
    'Leeteuk',
    'Heechul',
    'Han Geng',
    'Yesung',
    'Kangin',
    'Shindong',
    'Sungmin',
    'Eunhyuk',
    'Donghae',
    'Siwon',
    'Ryeowook',
    'Kibum',
    'Kyuhyun',
  ],
  bts: ['V', 'Jungkook', 'Jimin', 'Suga', 'Jin', 'RM', 'J-Hope'],
  exo: [
    'Kai',
    'D.O.',
    'Baekhyun',
    'Chanyeol',
    'Sehun',
    'Chen',
    'Suho',
    'Lay',
    'Xiumin',
  ],
  exid: ['Solji', 'LE', 'Hani', 'Hyerin', 'Jeonghwa'],
  blackPink: {
    southKorea: { vocalist: 'Jisoo', rapper: 'Jennie' },
    newZealand: {
      vocalist: 'Rosé',
    },
    thailand: {
      dancer: 'Lisa',
    },
  },
  duetSongs: [
    'Winter Flower',
    'Fear',
    'Dally',
    'I Wanna Be',
    'Black',
    'No One',
    'Refresh',
    'Eight',
  ],
  superM: {
    shinee: {
      vocalist: 'Taemin',
    },
    exo: {
      vocalist: 'Baekhyun',
      dancer: 'Kai',
    },
    nct127: {
      rapper1: 'Taeyong', // Open 24 hours
      rapper2: 'Mark',
    },
    wayv: {
      dancer: 'Ten',
      rapper: 'Lucas',
    },
  },

  duet: function (peformer1, performer2, songChoice) {
    return [
      this.superJunior[peformer1],
      this.exid[performer2],
      this.duetSongs[songChoice],
    ];
  },

  jukebox: function ({ performer1 = 1, performer2 = 0, songChoice = 3 }) {
    console.log(
      `Mash-up! ${this.superJunior[performer1]} and ${this.exid[performer2]} will sing ${this.duetSongs[songChoice]}.`
    );
  },
};

Destructuring Objects Within an Object

As was the case in array destructuring, we are able to pull elements within the k-pop object.

1 const { bts, exo, blackPink } = kpop;
2 console.log(bts, exo, blackPink);

We were able to pull individual items within the main object element. In this, we pulled from the bts, exo, and blackPink objects.

For those new to Javascript Programming, you have to declare the existence of a thing before you can call forth that thing. In this case, we use the “const” in line 1 to denote what we’re calling and where it’s originally coming from. Think of it as calling out a person’s name in a crowd and trying to get a specific person’s attention. You really can’t get away with saying “Hey You” and have that person you’re calling out know you’re speaking to them when you’re in a crowded room. There’s only one time in Javascript when you can get away with the “hey you” behavior and it’s called an “unnamed function”, which we covered in our Javascript: Functions (Uncle Roger Edition) post.

With the bts, exo, and blackPink origins declared in line 1, we can use the “console log” command to tell us what are inside these three elements. Below is our output:

As we can see from our foundation code, the three elements we requested (bts, exo, and blackPink) all pulled up with their contents. The first two are actually arrays, so both of their contents came up with only their names. BlackPink is actually an object within the k-pop object, so the output for that element looks different than that of the arrays.

If we were to destructure these elements further, we could, but, as we did in the array destructuring post, we would need to assign a new name for each, sub-element as we did in the BBMak example.

Parent/Child Calls (Not Destructuring)

If you just want to pull the sub-elements, without them destructured, you can do it using the parent/child call method, as listed below for blackPink:

console.log(bts[5], exo[0], blackPink.thailand.dancer);

BTS and EXO examples are arrays, so whatever number in the “[ ]” will be associated with the array element within their groups “in order”, starting with the number “0”. So even though we know there are 7 members of BTS, their members break down into element number 0-6.

This is not destructuring. Destructuring requires me to assign a new name for a single value outside of an object or array. Because a new name has not been assigned to all three of these calls, the output is only a response to an object call.

The output of this console log returns:

RM Kai Lisa

Destructuring Objects within an Object

As for blackPink, that element is an object and if you want to retrieve something within that object, you’re going to have to use the parent/child methods. Although more common when working with the DOM (document object model) parent/child calls are a common feature in many programming languages, not only in Javascript. In JS programming, you’ll see it as “(parent element) . (child element)”, and it can go deeper than just one generation. In our blackPink example, we go two levels deep to get the element we want. We ask JavaScript to pull the following:

blackPink.newZealand.vocalist
  1. Go into blackPink object, go to step 2.
  2. Select the newZealand object, go to step 3.
  3. We want whatever is listed in the vocalist object.

In this case, Rose is listed as the person within this group.

Again, this final method does not make it into a destructed element, since we did not give this search parameter a name, however, if we did this:

1 const blackPinkRose = blackPink.newZealand.vocalist;
2 console.log(blackPinkRose);

The object that’s within the “blackPink.newZealand.vocalist” object becomes it’s own destructed object element outside of its parent object and is confirmed by the output of line 2 as “Rose”.

Destructured Default Values and Arguments for Functions

In the final part of our foundation code, you may have noticed two functions, one called “duet” and the other called “jukebox”. The duet function establishes the origin for where the arguments (references) will be associated with in the “kpop=this” object. The jukebox function establishes the default values if no elements are included in the argument input and what the final result will return.

For reference, this is what it looks like (this is a snippet and will not function on it’s own):

duet: function (peformer1, performer2, songChoice) {
    return [
      this.superJunior[peformer1],
      this.exid[performer2],
      this.duetSongs[songChoice],
    ];
  },

  jukebox: function ({ performer1 = 1, performer2 = 0, songChoice = 3 }) {
    console.log(
      `Mash-up! ${this.superJunior[performer1]} and ${this.exid[performer2]} will sing ${this.duetSongs[songChoice]}.`

If you aren’t sure how functions work, head over to my post on JavaScript: Functions (Uncle Roger edition) for more information.

For our first function call, we will use this:

1 kpop.jukebox({
2  performer1: 0,
3  performer2: 3,
4  songChoice: 4,
5 });

We are asking the jukebox function to do the following:

  • From the “kpop.jukebox” object, use the following:
    • performer1 slot, use array element “0”
    • performer2 slot, use array element “3”
    • songChoice slot, use array element “4”
  • Console will log all this into the established sentence and will replace inputted value into the assigned argument slots of “performer1”, “performer2”, and “songChoice”.

This is the output:

Mash-up! Leeteuk and Hyerin will sing Black.

Performer1 takes from the SuperJunior array, performer2 takes from the EXID array, while songChoice takes from the duetSongs array and each number corresponds with an element in that array.

What does this have to do with destructuring?

The console log and the return in both the duet and jukebox functions require an object pull to be made and established into its own, which is now tied to the final console log.

For sample number #2, we will use the default options and only choose the song:

kpop.jukebox({
  songChoice: 7,
});

…and the outcome is this:

Mash-up! Heechul and Solji will sing Eight.

The default values for performer1 = superJunior[1] (Heechul) and perferformer2 = exid[0] (Solji). Whenever you see the word “this.<something>”, the “this” is referring to the object/function that is the parent of what it’s currently in. In this case, that would be the kpop object. So “this.superJunior[performer1]” = “kpop.superJunior[argument spot for “performer1″]”. We can also see it in the duet function coding. The only function call argument we used was the songChoice, which for array element 7 was the song “eight”.

Renaming Destructured Objects

When it comes to renaming destructed objects vs. arrays, objects are the easier of the two. In our array post, from our NKOTB and Boys II Men examples, both versions required the array order to be observed. Objects are pretty much like tic tacs in a container vs arrays like mentos in a roll. We don’t have to say “give me the third piece from the front” when referring to objects. In the case of objects, it’s pretty straight forward:

1 const { bts: bangtanBoys, exo: exoplanet, blackPink: prettySavage } = kpop;
2 console.log(bangtanBoys, prettySavage, exoplanet);

The renaming of the object elements happens in the “const” and the output of line 2 gives us this:

Since we swapped the order between blackPink and exo, we can also see it did not stop us from getting our requested output. In arrays, positioning is everything, in objects, positioning isn’t important.

Destructured Default Values

In JS programming land, we are able to create destructured default objects even if it’s not in an object. To explain, let me start with the coding we’re going to be working with:

1 const { ioi = [], superJunior: southKorea = [] } = kpop;
2 console.log(ioi, southKorea);

When you see this code, you notice that within the object in line 1, it says “ioi = [ ]” and if you go up to the foundation code, you will notice that “ioi” isn’t in the code. However, the superJunior object is listed as “= kpop” code meaning, the origin of these elements is within the kpop object.

New element is NOT an error.

Normally, if there’s an error in a JavaScript code, the entire code won’t execute, and it can be something as arbitrary as forgetting your punctuation. However, in this case, the empty array isn’t seen as an error, but a declaration, and even though it’s saying at the end of line 1 that whatever is in these brackets “{ }” is from the “kpop” object, it WASN’T added into the “kpop” object, nor is it part of it.

The partnering element in this code, “superJunior” array name is renamed as “southKorea”. The “=” sign means that southKorea now becomes the default name of the previously known superJunior array. To confirm this, the console log in line 2 produces the following result:

As expected, “ioi” came up as an empty array, while SuperJunior, with their 13 lifetime members came up when we invoked the “southKorea” array.

(Trivia side note: Super Junior disbanded in 2020, which is why I renamed the array “southKorea” to reflect that the members folded back to their country of origin. I.O.I was an ensemble group that was created temporarily for a project, and as a group, is no longer together. )

Nested Objects

In our last case study involving our foundation code, we look at nested objects. We will use the group “Super M”, which is a kpop group that was formed from members of four different groups (shinee, exo, nct127, and wayv). This example will show how we destructure objects within objects, within other objects.

1  const {
2   exo: { vocalist: v, dancer: dance },
3  } = kpop.superM;
4  console.log(v, dance);

In the above code, the destructuring happens in lines 1-3.

  • Line 3, we tell JavaScript to pull the references from the parent object “kpop” into the sub-object “superM”.
  • In line 2, we reference the final sub-object to pull from.
  • We also change the name of the value, but not the value itself, updating the vocalist element name to “v” and the dancer element name to “dance”.

Legitimately, you could have used this code instead:

1 const { vocalist: v, dancer: dance } = kpop.superM.exo;
2 console.log(v, dance);

Either would have worked just as well.

The console will log the same result for either of the two:

Baekhyun Kai

In the superM object within the kpop object, Baekhyun is listed as the vocalist while Kai is listed as dancer.

Now let’s use this on the blackPink sub-object:

1 const { vocalist: vocal, rapper: m } = kpop.blackPink.southKorea;
2 console.log(vocal, m);

and the return of this is:

2 Jisoo Jennie

We are able to destructure these values outside of the kpop, soutKorea, and blackPink objects.

Isn’t this like objects within nested objects?

In a way, this is almost exactly like destructing objects within an object. However, we are able to do it with multiple values within a child object while changing its element name. If you attempted to rename the call within an object:

const {blackPink.thailand.dancer: dance} = kpop;

…you will get the following error message:

Uncaught SyntaxError: Unexpected token '.'

Javascript doesn’t like code blocks that involve parent/child breakdowns within its objects. This is why we try to establish relationships outside of the object brackets “{ }” as much as possible.


If you haven’t figured it out yet, “:” works within an object while “=” outside of an object. Although it seems confusing at first, when dealing with arrays or objects, realize that this only works within an object, but not outside of one.

exid: ['Solji', 'LE', 'Hani', 'Hyerin', 'Jeonghwa'];

…while below will work outside of an object, but not inside of one.

let exid = ['Solji', 'LE', 'Hani', 'Hyerin', 'Jeonghwa']

Mutating Variables

This is when object destructuring takes an unusual turn. In our foundation code, we’re going to use three of the nine members of the girl group Twice and have their record label change two of the member’s ages.

1 let jihyo = 24;
2 let nayeon = 26;
3 const twiceAges = { jihyo: 21, nayeon: 22, jeongyeon: 25 };

Usually, the rule of thumb is if you change the value of an element, the last value becomes the final value, so in the case of the code above, line 3 should reset the values of “jihyo” and “nayeon” to 21 and 22 respectively. When we console log both, the results aren’t what you’d expect:

4 console.log({ jihyo, nayeon });
5 console.log(twiceAges);

Because line 3 changed the values, line 4 normally would not have come back with the original “let” values, while line 5, which called back to the “twiceAges” objects reproduced the altered values of “jihyo” and “nayeon”.

Inside and Outside Object Rules

So what happened? Although lines 1 and 2 declared a value for “jihyo” and “nayeon”, they were both added to the “twiceAges” object. Whatever is in an object only lives within that object. Even if they originated outside of an object, when they are added inside an object, whatever happens in there, stays in there. Kind of like Las Vegas.

Changes that happen inside objects on outside elements do not affect that outside element. The inside object becomes an alternate universe, where the changes only existed within that timeline. So when we look at output line 4, we see the original two values, and line 5 produced the new values. To confirm this is the case, we go one further to confirm this “alternate reality” object destructured change:

6 let jisoo = twiceAges.jihyo;
7 console.log(jisoo);
8 console.log(jihyo);

To make things less confusing, we renamed the “twiceAges.jihyo” element to “jisoo”, which is her real name (Park Ji Soo).

7 21
8 24

We created mutating values for one element. If we never gave a new value to “jihyo”, it would have been a much different outcome:

1 let jihyo = 24;
2 let nayeon = 26;
3 const twiceAges = { jihyo, nayeon: 22, jeongyeon: 25 };
4 console.log({ jihyo, nayeon });
5 console.log(twiceAges);
6 let jisoo = twiceAges.jihyo;
7 console.log(jisoo);
8 console.log(jihyo);

Inputs above, outputs below.

4 {jihyo: 24, nayeon: 26}
5 {jihyo: 24, nayeon: 22, jeongyeon: 25}
7 24
8 24

In line 3 of our new foundation code, “twiceAges” did not alter the “jihyo” value, but “nayeon” did change.

I think I just figured out The Avenger’s “time heist” theory, or the multiverse in Spider Man.

Thanks for reading!

For more on destructuring objects, click on the links below: