DEV Community

Cover image for Why copying can be tricky?
Przemek Wolnik
Przemek Wolnik

Posted on

Why copying can be tricky?

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:

assignment operator

You can play with code here:
Edit blissful-jepsen-ivzn7

2. Object.assign / Object spread operator

Object.assign creates shallow copy of the object:

object spread operator

Edit empty-dew-6eb6v

3. Ramda clone

R.clone creates deep copy of the object:

ramda clone

Edit musing-rgb-rm291


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)

Collapse
 
javaguirre profile image
Javier Aguirre

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. :-)

Collapse
 
przemwo profile image
Przemek Wolnik

Thanks for kind words! lodash looks like a good choice here as well.