Learn to Code via Tutorials on Repl.it!

← Back to all posts
Deep Cloning Objects
Coder100

Deep Cloning Objects

Why should one even be interested in this one may ask? Because it will most definitely affect you in many aspects. This is one of the most annoying properties of JS.

?!?! myArr is constant!! wtf!!

Reason

I am sure you will find a real world application that concerns two arrays like in this example. Before we discuss a solution, let's first talk about why this is.

When you pass in numbers to be copied:

And even strings (remember, in JS, strings are not array pointers like in C and C++):

it copies by value. This is very much what is expected. In the backend, what happens is that the value is passed, and everyone is happy! However, objects and arrays in the backend are just pointers to memory addresses, and you are being given the pointer! Not what you want at all!

Shallow Copy

Naively, to combat this, one would probably do something like this:

And all is good! However, is it though?

That's right, it only made a shallow copy. Only the first things got copied, nothing else!

Deep Copy

To implement a deep copy, all we need to do is deep copy objects within objects. It's quite simple, and here's my implementation of it:

If the argument isn't an object (which we will see later), we just return the object as it will be passed by value, and if it is an object, we just create a new object that gets assigned key by key with copies of the value of the key.

Now, our example looks like this:

it copied! However, the output isn't really an array anymore...

Array Copy

For arrays, we just need to map the values, and the function looks something like this:

A very nice recursive solution like the object copy.

Conclusion

Everything is passed by value except for objects. Those are stored as pointers, and will be passed by reference. In order to remedy this, we defined two functions.

And special thanks to @fuzzyastrocat, here's a function that accomplishes both:

Now, with these functions at your disposal, go forth and complete the aoc!

Voters
Spotandjake
Wilke000
Highwayman
coder400
forceofyoda
joehsu168
TYRONEMLG
EpicRaisin
dudeactualdev
lperras
Comments
hotnewtop
CursorsDev

owo i cant believe that JSON.parse(JSON.stringify(object)) deep copies the object lmao

CursorsDev

i mean your typical object

RayhanADev

I wish I understood any of this ( -.-)

Me before reading this:

Me after reading this:

HackermonDev

YES! I always have problems with this while coding, thx for the tutorial.

Coder100

yeyeye np :))) @PDanielY

xxpertHacker

What about TypedArrays, Sets, Maps, DataViews, ArrayBuffers, DOM objects, RegExps, Dates, etc?

Kasey00

Note that your solution won't preserve classes either (unless I've missed something).

fuzzyastrocat

Nice, however I'd put a word of caution in this. By definition, cloning an object is expensive performance-wise (and memory-wise for that matter). So, if you're needing to use this a lot then there's probably a better, more efficient way to solve the problem.

However, this is definitely needed sometimes, so I'm not saying it should never be done.

(Is that a typo on line 5 of the copyObj function? Shouldn't it be copyObj( not copy(?)

Also, here's a single function that can do both objects and arrays:

Coder100

definitely!
I don't encounter this often (previously I just gave up and rethought my implementation), but I found this useful for tiny projects like an AOC challenge @fuzzyastrocat

fuzzyastrocat

@Coder100 Cool, thanks for adding it to the post!
And yeah, it can definitely be super useful for little tricky problems.

iocoder

Thisis cool

@Coder100
Edit: sometimes i'll see typeof === object, or something like that, in the JS console when I'm running html or nodejs, does that have anything to do with this?

Coder100

@ridark yeah, it might, it really depends.
typeof === 'object' tells you if it is an object, but maybe they are just checking if it is an object lol

Zavexeon

You can also clone them like:

programmeruser

@Zavexeon the problem is that native objects aren't stored correctly. For example new Date() becomes "2020-12-08T20:26:56.863Z".

Coder100

yuck, you won't be able to preserve classes @Zavexeon

fuzzyastrocat

@Coder100 Note that your solution won't preserve classes either (unless I've missed something).

Coder100

instances? @fuzzyastrocat

fuzzyastrocat

@Coder100 Here's an example (I assume that's what you mean by "instances"):

JBloves27

Pretty cool! after i learn JS, ima have to read this ;)

Coder100

thx :))
you will very very very much want it! It took me so long to find out about why this even was a thing xd @JBYT27

JBloves27

xD ok! @Coder100