Picture of the author

Amit Khonde

JavaScript Interviews - Create a deep copy of an object

Many of us who have worked on any fairly large side projects or have contributed to other side projects must have come across JavaScript helper libraries like Lodash.js, Underscore.js. These libraries provide us with helper functions for things that JavaScript does not provide built-in. One of those functions is copying objects in JavaScript. A lot of us know how to copy objects which only have one level of nesting by Object Destructing. But if your object contains multiple nested levels, there is no in-built way in JavaScript to copy that object.

A lot of you might be wondering why this question is asked? If we have the helper library, why not just use that? And you are absolutely right. We should use that and we do use them indeed. But writing such a core function is going to test how you grasp and apply things fundamentally. As we will see later in this article, this question tests how you apply the knowledge that you already have. So let us get into some problem-solving mode 👨‍💻⚔️.

Problem Statement

Write a function that will take an object as an argument and returns a deep copy of that object.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // Signature function copyObject(source) { // Write your code here } // Usage const source = { a: 10, b: 20, c: { d: 30 } } const target = copyObject(source);

Before diving into the solution, I suggest that you try to solve this problem on your own. Here are some hints: - Forget about the nesting part. First, try to copy each key and value. - Now think about how you can identify if a value is an object itself and what to do with it.

Solution

When I am solving any problem, I always like to write the obvious things first. Those things can be found by reading the problem statement. The very obvious thing that the question asks is to return an object. So let us write that down first.

1 2 3 4 5 function copyObject(source) { var target = {}; return target; }

Now, the problem asks us for a deep copy of the object. But before jumping to deep copy, let us write a solution for copying each key value for a single level of nesting. So what do we need for that? - We need all the keys from the source object - Add all those keys one by one in the target object.

1 2 3 4 5 6 7 8 9 function copyObject(source) { var target = {}; const keys = Object.keys(source); keys.forEach(key => { target[key] = source[key]; }); return target; }

Great! So we have solved the problem for the simplest use case. Now let us think about nesting. So first of all, how will we know if the value corresponding to the current key is an object itself? By using typeof operator. And when we know that the current value is an object, how can we get its copy? –> By using the function that we are writing. I know this might sound confusing right now. This technique is known as Recursion (You can learn more about recursion here). Let us write the code and you will understand. So the final solution to the problem will look like this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function copyObject(source) { var target = {}; // Getting source object keys const keys = Object.keys(source); keys.forEach(key => { // Checking if current value is an object if (typeof source[key] === "object") { // Calling our function recursively for current value target[key] = copyObject(source[key]); } else { // Directly assigning the value target[key] = source[key]; } }); return target; }

Conclusion

Yay!! This looks like a working solution for now. There are minor problems with this solution like handling arrays and functions in objects. I would encourage you to write the code that will handle these conditions. And for more interesting questions like this, keep following this series. Until then, Happy Coding!!

Share

Share on twitter
Share on facebook

Like what you are reading? Subscribe for new posts every week