loading...

Copying Javascript Objects in an efficient way

ganeshmani profile image GaneshMani Originally published at cloudnweb.dev ・3 min read

There are different ways to copy an object in javascript. we will see how to copy javascript objects in an efficient way in this article.Copying Javascript Objects in an efficient way

Copying Javascript objects can be tricky. Most of the time, we will do shallow copy of an object in javascript.

But, there are few problems associated with that approach. But getting into that topic, we will see what is shallow and deep copy in javsacript.

Shallow vs Deep Copy

In javascript, shallow copy only clones the top level of an object. if an object contains the nested or reference object. it will copy only the reference to it.

Shallow Copy

For example, let's say you have an object like this

let data = {
  "id" : 1,
  "name" : "john",
  "address" : {
    "street" : "Sample",
    "country" : "Earth",
    "Street" : "Madison street"
  }
}

you are copying the object to a new variable using Object.assign

copydata = Object.assign({},data);

After that, if you console log the copydata variable. you will get the output like

Now, you are changing the variable data's object

data.address.street = "Changed Street";

if you console log copydata again, you will get output like,

it changes the copied object value too because the copied object will refer to the same object.

To solve this problem, deep copying is used in javascript.

Deep Copy

Meanwhile, deep copying in javascript clones the nested objects too and stores it in the different memory location.

So, changing the original object doesn't affect the cloned object.

Deep Clone in Javascript

it can be achieved using lodash util library in javascript which is one of the popular library in javascript ecosystem.

Install lodash in your machine to use it. After that, there is a method called clonedeep in lodash which is used to achieve the deep copying in javascript.

const _ = require('lodash');

let data = {
  "id" : 1,
  "name" : "john",
  "address" : {
    "street" : "Sample",
    "country" : "Earth",
    "Street" : "Madison street"
  }
}

let copydata = _.cloneDeep(data)

data.address.street = "Changed Street";

console.log("data => ",data);

console.log("==================================================================");


console.log("copydata =>",copydata)

Recent Articles

Crafting multi-stage builds with Docker in Node.js

Building a Production – Ready Node.js App with TypeScript and Docker

PM2 for Node.js developers

Posted on by:

ganeshmani profile

GaneshMani

@ganeshmani

Full Stack Engineer. Currently focusing on Javascript, React, GraphQL, and Nodejs.

Discussion

markdown guide
 

Thanks for the post.
Using lodash is not an efficient way, it's just the simplest way. Weight of lodash is 71k (24,7 gzipped), isn't too much for one function? A little better could be an import of just this function, but real efficiently is using own realizations.

import _ from 'lodash; // 71k (24,7k gzipped)
import cloneDeep from 'lodash/cloneDeep'; // 17,4k (4,8k) - it's still too much

let copyData = JSON.parse(JSON.stringify(data)) // how much? 32 bytes!

By the way, JSON.parse(JSON.stringify) is the most efficient way in JS to deep clone an object.

 

By doing json serialization, you will lose any Javascript property that has no equivalent type in JSON, like Function or Infinity. Any property that’s assigned to undefined will be ignored by JSON.stringify, causing them to be missed on the cloned object.

 

Yes, I agree with you. And I've noticed it in the comment below. But there are no functions or Infinity in your example, thus this way is the most efficient for objects like this.
For complicated objects, it's safer (safer, not faster) to use some custom realizations or even cloneDeep from lodash/cloneDeep (or just package 'lodash.cloneDeep'). But there are no reasons to pull the whole lodash library if you don't want to use all of its methods. It just inflates your bundle size.
So, let's come to a consensus: it’s good when you know your data and tools and select the tools suitable for the data and tasks :-)

 

But of course, this way is more dangerous because it doesn't have any checkings and if you want to use it, you have to add checking at least for recursive links.

 

There are lots of ways to deep copy and unfortunately no best way. This is partly because circumstances can differ. The JSON approach shown below for example wont work with anything but JSON data types.

The lodash method is likely to be well optimised as a general solution but if you have a specific solution try taking the lodash implementation then stripping out all but the code that needs to be there. You'll see that the specific implementation is much faster.

Libraries such as lodash are useful for getting certain things done quickly but are not well suited to high performance low footprint programming. I work with large complex apps that need to manage a lot of data and when I look at a library such as lodash I don't see a reduction in LOC or effort that makes it worth the performance hit and additional complexity the library brings.

I also need to trust my code 100% and that means in cases writing a hundred extra lines of helper functions instead of importing huge libraries. I just wrote a deep copy function for a new project a month back. It only cost less than a dozen lines and I've not had to modify it since.

To justify its use you have to be getting a lot more code coverage than from just using deep clone the use of which is highly unlikely to even achieve 100% coverage of that function.