-1

I have an object of mixed KnockoutJS observables and standard properties:

var original = {
  a: ko.observable("a"),
  b: "b"
};

I want to create a clone of the original object without any reference to it, so that I can do:

var cloned = clone(original);
cloned.a("a cloned");
original.a(); //-> "a" ERROR HERE

original.a("a original");
cloned.a(); //-> "a cloned" ERROR HERE

and

cloned.b = "b cloned";
original.b //-> "b" OK

original.b = "b original";
cloned.b //-> "b cloned" OK

I've tried with that function, but it caused the KnockoutJS observable properties to be copied, not cloned:

cloneObj = function(obj){
  if(obj === null || typeof obj !== 'object')
    return obj;

  var temp = obj.constructor(); // Give temp the original obj's constructor
  for (var key in obj) {
    temp[key] = cloneObj(obj[key]);
  }

  return temp;
};

As you can see in this fiddle http://jsfiddle.net/Ep3jY/ the problem only happens with KnockoutJS Observable properties while normal JavaScript properties get cloned correctly.

For now I use a workaround returning the object with a function, but that is quite annoying:

function(){
  return {
    a: ko.observable("a");
  };
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matteo Pagliazzi
  • 5,140
  • 12
  • 49
  • 83
  • http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object – HMarioD Dec 27 '12 at 13:18
  • sorry, the question is updated: the problem is with knockout observable properties while normal js properties get cloned correctly – Matteo Pagliazzi Dec 27 '12 at 13:24

1 Answers1

-1

Ok, it seems that the problem is with KnockoutJS observables. I solved this way:

cloneObj = function(obj){
  if(ko.isWriteableObservable(obj)) 
      return ko.observable(obj()); // This is the trick
  if(obj === null || typeof obj !== 'object') 
      return obj;

  var temp = obj.constructor(); // Give temp the original obj's constructor
  for (var key in obj) {
    temp[key] = cloneObj(obj[key]);
  }

  return temp;
};
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matteo Pagliazzi
  • 5,140
  • 12
  • 49
  • 83
  • 1
    didn't work for me. it's returning a referenced object to the source object. So if you change some value in the output object, it affects the passed one. – d-coder Feb 21 '13 at 04:19