How I Stopped Worrying and Learned to Love the Object II

The Spread Operator

Last time we checked out the difference between values and objects. Today we will learn how to copy an object’s properties using the spread operator. We can think of the spread operator like a cloning machine.

Let’s make our Superhero Bruce.

The Hero Javascript Needs
bruce = {};

And give him some properties.

bruce.age = 32;
bruce.height = 72;
bruce.hairColor = 'brown';

Now let’s clone bruce.

clonedBruce = {...Bruce};

Poof! We have a clone of bruce .Now what just happened? A new object was created that contains all the same properties as bruce. Let’s confirm.

bruce.age === clonedBruce.age; // true
bruce.height === clonedBruce.height; // true
bruce.hairColor === clonedBruce.hairColor; //true

Confirmed. Checking each property hand is time consuming and prone to error. Let’s write a function that does this instead. Note the ES6 function syntax.

var allPropsEqual = (obj1, obj2)=> {
//check to see if obj1 and obj 2 have the same number of keys
if (Object.keys(obj1).length!==Object.keys(obj2).length) {
return false;
}
//check if all key value pairs are the same
for (var key in obj1) {
if (obj1[key]!==obj2[key]) {
return false;
}
}
return true;
};

Now when we want to check if two objects have the same properties we can just use the allPropsEqual function.

areAllPropsEqual(bruce, clonedBruce); // true

Are Bruce and clonedBruce the same person? Just like identical twins they share all the same characteristics but they are different people. Likewise our bruce and clonedBruce objects have all the same properties but they are two different objects.

bruce === clonedBruce; // false

What if we wanted to clone bruce but change some of the properties on our clone? With spread operators this is a breeze.

var tallBlondeBruce = {
...bruce,
hairColor: 'blonde',
height: 120
};

Spread Operators With Nested Objects

Gotham’s premiere crime-fighter needs a hot set of wheels.

var batMobile = {
wheels: 6,
color: 'black',
horsePower: 2000,
bulletproof: 'true'
};
bruce.vehicle = batmobile;

Now let’s see what happens when we clone Bruce.

var clonedBruce = {...bruce};
bruce.vehicle === clonedBruce.vehicle; // true

The vehicle property is the same. That means both bruce and clonedBruce drive the batMobile. Another way to think of the same concept.

obj1 = {innerObj: 
{prop1: 'value1',
prop2: 'value2'}
};
obj2 = {...innerObj};

Take a moment to think about what we expect from the following scenarios.

obj1===obj2;
obj1.innerObj===obj2.innerObj;

The outer objects are not equal to each other, but all of there properties are equal. Both inner objects are equal to each other.

Bruce and clonedBruce are unhappy about sharing the batMobile. They each want there own car, but they both love the batMobile. To resolve this situation, let’s again clone bruce and give clonedBruce a vehicle that shares all the same properties of the batMobile.

clonedBruce = {
...bruce,
vehicle = {...bruce.vehicle}
};

Let’s check our expectations:

1. bruce and clonedBruce are two different objects.

bruce!==clonedBruce; // true

2. bruce.vehicle and clonedBruce.vehicle are two different objects.

bruce.vehicle === clonedBruce.vehicle // true

3. all of bruce.vehicle properties are the same as clonedBruce.vehicle properties

allPropsEqual(bruce.vehicle, clonedBruce.vehicle); // true

That is all for now. Stay tuned for part 3 where we will learn about object prototype and inheritance.