18

I am confused. I create a copy from myObjOne, than i delete an entry from myObjOne and JS delete the entry in my copy(myObjTwo) too? But why?

  myObjOne = {};
  myObjOne['name'] = 'xxx';
  myObjOne['id'] = 'yyy';
  myObjOne['plz'] = 'zzz';  

  // clone
  myObjTwo = myObjOne;

  // remove something
  delete myObjOne['name'];

  console.dir(myObjTwo);

example http://jsbin.com/itixes/edit#javascript,html

user970727
  • 1,947
  • 4
  • 22
  • 28
  • 1
    Take a look at [this question](http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object) – Ranhiru Jude Cooray Nov 01 '11 at 11:42
  • 2
    possible duplicate of [Copying an Object in Javascript](http://stackoverflow.com/questions/728360/copying-an-object-in-javascript) – Matt Nov 01 '11 at 11:45

8 Answers8

24

Update: Removing Object.create as a method of cloning as indicated in comments.

  myObjTwo = myObjOne;

does not clone. It simply copies the reference.

If you want to clone, you can use JSON.parse and JSON.stringify

var x = {a:{b:{c:{'d':'e'}}}};
var y = JSON.parse(JSON.stringify(x));  //y is a clone of x
console.log(y.a.b.c.d); //prints e
console.log(y === x); //prints false

Warning: As Raynos mentioned in comments, this JSON based clone does not retain methods of the input object in the output object. This solution is good enough if your object does not contain any methods. Methods are properties of a object that are functions. If var obj = {add : function(a,b){return a+b;}} then add is a method of obj.

If you need a solution that supports copying of methods, then go through these SO answers (as pointed out by musefan, Matt and Ranhiru Cooray)

I would suggest How do I correctly clone a JavaScript object?

Community
  • 1
  • 1
Narendra Yadala
  • 9,554
  • 1
  • 28
  • 43
  • a={name:1};b=Object.create(a);delete a.name; Now b doesn't have 'name' property either – spicavigo Nov 01 '11 at 11:50
  • `Object.create` does not make a clone but adds `x` to the prototype chain of `y`. – pimvdb Nov 01 '11 at 11:53
  • @pimvdb , spicavigo Thanks for pointing out. Removed `Object.create`. – Narendra Yadala Nov 01 '11 at 11:56
  • 1
    Using JSON to clone is expensive as hell and destroys methods. – Raynos Nov 01 '11 at 12:27
  • 1
    @Raynos Please feel free to update my answer if you wish to include a faster method. I think for simple objects, it is fast enough and concise. I also checked the jsperf http://jsperf.com/clone/2 before posting and it looks comparable. In any case please feel free to update. – Narendra Yadala Nov 01 '11 at 12:31
  • @Narendra a shallow property wise clone is [easy](https://github.com/Raynos/pd#pd.extend). A deep clone is a nightmare. JSON is a sensible solution, you just forgot to mention its limitations – Raynos Nov 01 '11 at 14:24
16

You can use jQuery like so:

var myObjTwo = jQuery.extend(true, {}, myObjOne);

The first argument indicates that we want to make a deep copy of myObjOne.

Nicu Surdu
  • 8,172
  • 9
  • 68
  • 108
3

That is not how you clone, that is simply storing the same original object in an extra variable. Maybe this answer will help you

Community
  • 1
  • 1
musefan
  • 47,875
  • 21
  • 135
  • 185
2

Lots of advice on how to make a copy not only of the object and it's properties, but of all the objects referenced by its properties. Here's a version that clones the object without copying it and so that the clone inherits all properties added later except for those shadowed by own properties of the clone:

var cloneOf = (function() {
  function F(){}
  return function(o) {
    F.prototype = o;
    return new F();
  }
}());

Some may recognise the pattern. An example:

var base = {foo:'foo', bar:'bar'};
var baseClone = cloneOf(base);
alert(baseClone.foo);  // foo
RobG
  • 142,382
  • 31
  • 172
  • 209
  • Why you use the prototype chain rather then copying properties over? – Raynos Nov 01 '11 at 12:28
  • Because it is one way to "clone" an object - the OP didn't say what was expected of the clone, so anything goes. – RobG Nov 01 '11 at 12:46
  • This works quite well. It works on objects with multiple nested objects/children and also functions. After you cloned the object, you can delete the "original", and the clone will be intact. – Jakob Sternberg Jan 18 '14 at 04:48
1

You can use Object.assign() but be aware of browser support.

More info here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.

Example:

myObjTwo = Object.assign({}, myObjOne);
Pablo
  • 2,540
  • 1
  • 18
  • 26
1

With ES6, use the spread operator.

myObjTwo = {...myObjOne}

The spread operator in es6 is just an ellipsis. It creates a copy of the original, even if the original is destroyed

Allan Mwesigwa
  • 1,210
  • 14
  • 13
0

Simple.

var clone=function(o){
      var n= {}.toString.apply(o)=="[object Array]" ? []:{};
      for(i in o)
         n[i]= typeof o[i]=='object' ? clone(o[i]):o[i];
      return n;
 };

Usage:

var x={a:{d:34},b:33};
var y=clone(x);  // clones 'x'
Dinesh
  • 1,126
  • 9
  • 6
0

Your line myObjTwo = myObjOne does not clone myObjOne, it just creates a duplicate reference to the same object!

The actual answer is to use a clone function, perhaps from a library such as underscore.js. But really, it looks like you have some reading and learning to do about the concept of objects and pointers in Javascript.

funkybro
  • 8,432
  • 6
  • 39
  • 52