There is a moment in the life of every programmer that you have to go back to the basics. I had that moment two days ago, when I wanted to bring the difference between React.Component and React.PureComponent to mind. The result of this return is this short article.
Traps of copying in JavaScript
Copying objects in JavaScript can be surprising. Example? Here you are.
This is information about my car SuperCar:
const myCar = {
make: "SuperCar",
year: 2016,
details: {
color: "blue"
}
};
You bought a new car (also SuperCar) and want to usemyCar
as a template to save information about it. You know that simple assignment operator is not a good choice. That's why you use object spread operator and write:
const yourCar = {...myCar};
Then you complete the relevant data about your car:
yourCar.year = 2019;
yourCar.details.color = "red";
console.log(yourCar.make); // "SuperCar"
console.log(yourCar.year); // prints 2019
console.log(yourCar.details.color); // prints "red"
Everything seems to be working properly. Until I try to write data about my car:
console.log(myCar.make); // "SuperCar"
console.log(myCar.year); // prints 2016
console.log(myCar.details.color); // prints "red" ?! WRONG!!!
What happened? By creating yourCar
we did shallow copy of myCar
. Variables holding primitive values (eg. numbers
, strings
) were actually copied. However, for those storing complex data (objects
), only references to the same objects were copied.
A detailed description of this mechanism you can find here.
Below I will present a visual cheat sheet of how this mechanism works in JavaScript. Whenever I have to re-think how it works, I will come back to this article. I hope you'll find it useful too.
Examples
All examples are based on the same task. I create the alice
object. Then I create the bob
object on the basis of alice
. I use for this:
1 Assignment operator
2 Object.assign
method (or object spread operator)
3 clone
method from Ramda library
1. Assignment operator
Assignment operator creates reference to the same object:
2. Object.assign / Object spread operator
Object.assign
creates shallow copy of the object:
3. Ramda clone
R.clone
creates deep copy of the object:
Thanks for reading! If you liked this let me know! Leave a comment, give a ❤️ or share it!
Feel free to check my Twitter account with more content like this.
Top comments (2)
Great explanation! I really like the pictures. :-)
I often use lodash cloneDeep being usually a dependency in my projects, but Ramda seems a good option too. :-)
Thanks for kind words! lodash looks like a good choice here as well.