Hi everyone, and welcome to another EXCITING edition of Boring JavaScript! In this post, we tackle the Object.assign() method, great for merging and copying objects.
Or is it?
Keep reading to find out, or watch our video on the matter.
Two Parts Flour, One Part Butter, and Mix
Object.assign() merges the contents of one or more objects into a target object. The syntax is easy. Let’s take a look
const myAnimals =
{ "Cat": "Fluffy", "Dog": "Fido", "Horse": "Mr. Ed", "Cow": "Betsy" };
const yourAnimals =
{ "Coyote": "Wile E.", "Road Runner": "Beep Beep", "Dolphin": "Flipper", "Whale": "Moby Dick", "Lizard": "Larry" };
const allAnimals = Object.assign(yourAnimals, myAnimals);
console.log(myAnimals);
console.log(yourAnimals);
console.log(allAnimals);
Line 6 contains the Object.assign syntax. It takes at least two arguments. The first argument is the target object into which the other objects – specified by the second argument and more – are merged. In the above example, ‘myAnimals’ will not get changed, but the properties of ‘myAnimals’ will get merged into ‘yourAnimals’ which means that the first argument – the target object – will get changed by the operation. Object.assign() will also return the target argument, so if you run the above code, you get the following:
{ Cat: 'Fluffy', Dog: 'Fido', Horse: 'Mr. Ed', Cow: 'Betsy' }
{
Coyote: 'Wile E.',
'Road Runner': 'Beep Beep',
Dolphin: 'Flipper',
Whale: 'Moby Dick',
Lizard: 'Larry',
Cat: 'Fluffy',
Dog: 'Fido',
Horse: 'Mr. Ed',
Cow: 'Betsy'
}
{
Coyote: 'Wile E.',
'Road Runner': 'Beep Beep',
Dolphin: 'Flipper',
Whale: 'Moby Dick',
Lizard: 'Larry',
Cat: 'Fluffy',
Dog: 'Fido',
Horse: 'Mr. Ed',
Cow: 'Betsy'
}
Both ‘yourAnimals’ and ‘allAnimals’ are the same object. Therefore, you really never need to capture the returned value from Object.assign(), as that will always be the target object – EXCEPT – if your target object is a blank Object, then you will need to capture the return value or lose it.
// here, you need 'const allAnimals' as it makes a straight copy of 'myAnimals'
const allAnimals = Object.assign({}, myAnimals);
Hey! You Look Just Like Me!
What happens if two properties on the objects are the same? The property in the target object will be replaced. Consider the following code:
const myAnimals =
{ "Cat": "Fluffy", "Dog": "Fido", "Horse": "Mr. Ed", "Cow": "Betsy" };
const yourAnimals =
{ "Coyote": "Wile E.", "Cat": "Mr. Jingles" };
Object.assign(yourAnimals, myAnimals);
console.log(myAnimals);
console.log(yourAnimals);
/* Output:
{ Cat: 'Fluffy', Dog: 'Fido', Horse: 'Mr. Ed', Cow: 'Betsy' }
{
Coyote: 'Wile E.',
Cat: 'Fluffy',
Dog: 'Fido',
Horse: 'Mr. Ed',
Cow: 'Betsy'
}
*/
The property “Cat” appears in both “yourAnimals” (as Mr. Jingles) and in “myAnimals” (as “Fluffy”). When Object.assign() was finished, notice now that “yourAnimals” has the “Cat” value of “Fluffy”. This shows that any duplicate properties are replaced in the target object.
But wait! There’s more!
You’re not limited to only one source object. You can have as many source objects as you want, and they will all get copied to the target object. Let’s take a look at that.
const myAnimals =
{ "Cat": "Fluffy", "Dog": "Fido", "Horse": "Mr. Ed", "Cow": "Betsy" };
const coyote = { "Coyote": "Wile E." };
const roadRunner = { "Road Runner": "Beep Beep" };
const dolphin = { "Dolphin": "Flipper" };
const whale = { "Whale": "Moby Dick" };
const lizard = { "Lizard": "Larry" };
const beluga = { "Whale": "Beluga"};
console.log('\nBEFORE');
console.log(myAnimals);
Object.assign(myAnimals, coyote, roadRunner, dolphin, whale, lizard, beluga);
console.log('\nAFTER');
console.log(myAnimals);
Notice now that there are now six source objects in the Object.assign. Each one of these will get merged in turn, one at a time, into the target object.
Also notice that there is a repeat in the source objects – there is one ‘whale’ and another ‘whale’ belonging to the variable ‘beluga’. What will happen? Let’s take a look at the output:
BEFORE
{ Cat: 'Fluffy', Dog: 'Fido', Horse: 'Mr. Ed', Cow: 'Betsy' }
AFTER
{
Cat: 'Fluffy',
Dog: 'Fido',
Horse: 'Mr. Ed',
Cow: 'Betsy',
Coyote: 'Wile E.',
'Road Runner': 'Beep Beep',
Dolphin: 'Flipper',
Whale: 'Beluga',
Lizard: 'Larry'
}
Out ‘whale’ property has the value of ‘Beluga’, and not ‘Moby Dick’. This shows that Object.assign() takes the source objects in the order that you specify them. The whale ‘Moby Dick’ was merged in first (from the variable ‘whale’), and then the whale ‘Beluga’ was merged in next – since it was listed after the variable ‘whale’.
It’s Not All Rainbows and Unicorns
Object.assign() is great for merging objects or even creating a new object (just pass an empty object as the target argument). But all is not what it seems. Object.assign() will copy the values from the source objects only if they are ‘primitive’ values, such as strings, booleans, numbers, etc. That’s not the case for more complex data such as objects within objects. There the reference to the object is passed and not the value.
What does that mean? Let’s take a look:
const myAnimals = {
Cat: "Fluffy",
Dog: "Fido",
Horse: {
name: "Mr. Ed",
trait: "Talks a lot"
}
}
const yourAnimals = {
Coyote: "Wile E.",
Whale: "Moby Dick"
}
Object.assign(yourAnimals, myAnimals);
console.log('\nBEFORE NAME CHANGE');
console.log(yourAnimals);
myAnimals.Horse.name = "Wild Fire";
console.log('\nAFTER NAME CHANGE');
console.log(yourAnimals);
After the Object.assign completes, ‘yourAnimals’ will have a copy of ‘myAnimals’. Specifically, it will make copies of ‘Cat’ and ‘Dog’, as they are primitive values. ‘Horse’ is not – it’s an Object, and therefore a reference will be copied, but the physical object will not.
What does that mean? If you change a property of ‘Horse’ in the variable ‘myAnimals’, it will change in both ‘myAnimals’ and ‘yourAnimals’. That is because a physical copy of ‘Horse’ was not made – each entry of ‘Horse’ in ‘myAnimals’ and ‘yourAnimals’ points to the same data.
What happens if we change the name of the horse? Let’s find out – here is the output to the above code:
BEFORE NAME CHANGE
{
Coyote: 'Wile E.',
Whale: 'Moby Dick',
Cat: 'Fluffy',
Dog: 'Fido',
Horse: { name: 'Mr. Ed', trait: 'Talks a lot' }
}
AFTER NAME CHANGE
{
Coyote: 'Wile E.',
Whale: 'Moby Dick',
Cat: 'Fluffy',
Dog: 'Fido',
Horse: { name: 'Wild Fire', trait: 'Talks a lot' }
}
Notice that the name of the Horse changed from ‘Mr. Ed’ to ‘Wild Fire’.
So be careful! As wonderful as Object.assign() is at copying and merging objects, it can have pitfalls if your objects contain anything other than simple primitive values. If you have objects, you will need to do something called “Deep Cloning” – a subject outside of this course.
The Video
Of course, we also have a video ready for you in case you don’t like to read.
Shameless Plugs
Check us out all over the ‘Net!
Check out all our videos at: https://www.boringjavascript.com
Check out everything at: https://www.thevirtuoid.com
Facebook: https://www.facebook.com/TheVirtuoid
Twitter: https://twitter.com/TheVirtuoid
YouTube: https://www.youtube.com/channel/UCKZ7CV6fI7xlh7zIE9TWqgw
Categories: Boring JavaScript Javascript
thevirtuoid
Web Tinkerer. No, not like Tinkerbell.
Creator of the game Virtuoid. Boring JavaScript. Visit us at thevirtuoid.com
Leave a Reply