0

I've been reading about cloning and everyone seems to be using some complicated code. I guess that I might be doing it wrong, but it seems to be working, and when changing values of "cloned" object properties, my main object does not change.

var clonedObject ={};
//randomItem is main object, which I want to clone
for (var key in randomItem) {
    if (randomItem.hasOwnProperty(key)) {
        clonedObject[key] = {};
        clonedObject[key] = randomItem[key];
    }
};
return clonedObject;

It works for me, please tell me if there is something wrong with that? I am confused since this seems too easy compared to what other posts says about it(tho some of them are 7 years old). Thanks

Mariusz
  • 361
  • 1
  • 4
  • 17
  • 2
    You can always just do: `var clone = JSON.parse(JSON.stringify(originalObj))` – tymeJV Jan 20 '16 at 16:16
  • 1
    Yes its a right way to do that why are u confused ? – Wasiq Muhammad Jan 20 '16 at 16:17
  • 3
    @tymeJV — Only if the values are all primitive. It will break the moment you put complex objects in there. – Quentin Jan 20 '16 at 16:17
  • that wont do a deep clone - the `complicated` code probably DOES deep cloning (possibly optionally) – Jaromanda X Jan 20 '16 at 16:18
  • I'm voting to close this question as off-topic because it is asking for [a code review](http://codereview.stackexchange.com/help/on-topic) – Quentin Jan 20 '16 at 16:18
  • Hey, thanks for letting me know. I was confused because I read some old posts on this site, which were writting like 30 lines of the code, to clone an object. I am glad it is the right way :) Thanks. – Mariusz Jan 20 '16 at 16:19
  • @Quentin Hey, I wasnt sure how to post this in off-topic, but if it can be moved then thats fine with me. – Mariusz Jan 20 '16 at 16:20
  • 2
    All the suggestions you could want: [Most elegant way to clone a JavaScript object](http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object) – scniro Jan 20 '16 at 16:24
  • @Quentin this would not fare very well on Code Review as it looks like example code. Code Review requires real code in its context rather than small snippets like this one. – Phrancis Jan 20 '16 at 16:39

2 Answers2

1

Here is a quick example where you can see how your code behaves with nested objects compared to a real deep clone:

var x = {a:{a:1}};

function update () {
  document.getElementById('x').textContent = JSON.stringify(x);
  document.getElementById('y').textContent = JSON.stringify(y);
  document.getElementById('z').textContent = JSON.stringify(z);
}

// This is your code
function yourClone (randomItem) {
  var clonedObject ={};
  for (var key in randomItem) {
    if (randomItem.hasOwnProperty(key)) {
      clonedObject[key] = {};
      clonedObject[key] = randomItem[key];
    }
  };
  return clonedObject;
}

// This is a real deep clone taken from http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object
function deepClone (obj) {
  var copy;

  // Handle the 3 simple types, and null or undefined
  if (null == obj || "object" != typeof obj) return obj;

  // Handle Date
  if (obj instanceof Date) {
    copy = new Date();
    copy.setTime(obj.getTime());
    return copy;
  }

  // Handle Array
  if (obj instanceof Array) {
    copy = [];
    for (var i = 0, len = obj.length; i < len; i++) {
      copy[i] = deepClone(obj[i]);
    }
    return copy;
  }

  // Handle Object
  if (obj instanceof Object) {
    copy = {};
    for (var attr in obj) {
      if (obj.hasOwnProperty(attr)) copy[attr] = deepClone(obj[attr]);
    }
    return copy;
  }

  throw new Error("Unable to copy obj! Its type isn't supported.");
}


function inc() {
  x.a.a++;
  update();
}
<body onload="y=yourClone(x);z=deepClone(x);update()">
  x: <span id="x"></span><br/>
  y: <span id="y"></span> &lt;- your clone from 'x'<br/>
  z: <span id="z"></span> &lt;- real deep clone from 'x'<br/><br/>
  <button id="inc" onclick="inc()">Increment nested element in x</button>
</body>

When you copy the value of some variable into another variable, depending on the type of data, you will be copying the value itself (numbers and text) or just a reference to the data (dates, arrays and objects). When you deal with references, you will need to go recursively into the next level and copy all the values into the new object in order to create a new instance.

Javier Conde
  • 2,553
  • 17
  • 25
  • Hey, your code snippet is not working for me. I understand more or less deep/shallow copying. If I have nested objects I need to do a deep copy. Does that mean, code above (deep copy) will copy all nested objects on all levels? Like: `var myObj = {a:{b:{c:{d:{}}}}}` Will it copy it exact same way? Also does it copy functions which are inside properties? That would be nice too :) – Mariusz Jan 20 '16 at 18:31
  • I edited it to use `textContent` instead of `innerText` so it work across browsers. Yes, the code above will copy recursively all the levels of the object including functions :) – Javier Conde Jan 20 '16 at 18:44
  • Thanks, that will be useful :) – Mariusz Jan 20 '16 at 19:34
-1
// Shallow copy
var newObject = jQuery.extend({}, oldObject);

// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);

What is the most efficient way to deep clone an object in JavaScript?

in nodeJS I'm using underscore module let newObj = _.clone(oldObj);

Community
  • 1
  • 1