带有KnockoutJS可观察属性的JavaScript克隆对象

JavaScript clone object with KnockoutJS observable properties

本文关键字:JavaScript 对象 属性 KnockoutJS 观察 带有      更新时间:2023-09-26

我有一个混合的KnockoutJS可观察对象和标准属性:

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

我想创建一个没有任何引用的original对象的克隆,这样我就可以做:

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

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

我已经尝试过这个函数,但它导致KnockoutJS的可观察属性被复制,而不是克隆:

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;
};

你可以看到在这个提琴http://jsfiddle.net/Ep3jY/问题只发生在KnockoutJS的可观察属性,而正常的JavaScript属性克隆正确。

现在我用一个函数返回对象,但这很烦人:

function(){
  return {
    a: ko.observable("a");
  };
}

好吧,似乎问题是与KnockoutJS的可观察对象。我是这样解决的:

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;
};