这取决于您想克隆什么。这是一个真正的 JSON 对象还是 JavaScript 中的任何对象?如果您想要任何克隆,可能会让您陷入一些麻烦。有哪些麻烦呢?我将在下面解释,但首先是一个代码示例,它可以克隆对象字面量、任何基本类型、数组和 DOM 节点。
function clone(item) {
if (!item) { return item; }
var types = [ Number, String, Boolean ],
result;
types.forEach(function(type) {
if (item instanceof type) {
result = type( item );
}
});
if (typeof result == "undefined") {
if (Object.prototype.toString.call( item ) === "[object Array]") {
result = [];
item.forEach(function(child, index, array) {
result[index] = clone( child );
});
} else if (typeof item == "object") {
if (item.nodeType && typeof item.cloneNode == "function") {
result = item.cloneNode( true );
} else if (!item.prototype) {
if (item instanceof Date) {
result = new Date(item);
} else {
result = {};
for (var i in item) {
result[i] = clone( item[i] );
}
}
} else {
if (false && item.constructor) {
result = new item.constructor();
} else {
result = item;
}
}
} else {
result = item;
}
}
return result;
}
var copy = clone({
one : {
'one-one' : new String("hello"),
'one-two' : [
"one", "two", true, "four"
]
},
two : document.createElement("div"),
three : [
{
name : "three-one",
number : new Number("100"),
obj : new function() {
this.name = "Object test";
}
}
]
})
现在,让我们谈一谈在开始克隆真实对象时可能会遇到的问题。我现在所说的是指通过类似于下面这样的方式创建的对象:
var User = function(){}
var newuser = new User();
当然可以克隆它们,这不是问题,每个对象都公开了构造函数属性,您可以使用它来克隆对象,但这并不总是起作用。您也可以在这些对象上执行简单的
for in
操作,但这会带来问题。我还在代码中包含了克隆功能,但它被
if(false)
语句排除了。
那么,为什么克隆可能是个麻烦?首先,每个对象/实例可能都有一些状态。您永远无法确定您的对象是否具有例如私有变量之类的状态,如果是这种情况,在克隆对象时,您只会破坏状态。
假设没有状态,那就没问题了。那么我们仍然有另一个问题。通过“构造函数”方法进行克隆将给我们带来另一个障碍。它是一个参数依赖性。您永远无法确定创建此对象的人是否做过某种
new User({
bike : someBikeInstance
});
如果是这种情况,那么你就很遗憾了,someBikeInstance可能是在某个上下文中创建的,而克隆方法不知道该上下文的存在。
那怎么办呢?你仍然可以使用for in
的解决方案,并将此类对象视为普通对象文字使用,但最好不要克隆这样的对象,而只需传递此对象的引用即可。
另一个解决方案是 - 您可以设置一个约定,即所有必须克隆的对象都应自行实现此部分并提供适当的API方法(例如cloneObject)。类似DOM中的cloneNode
所做的事情。
由您决定。
JSON.parse(JSON.stringify(o))
和$.extend(true, {}, o)
,但我不想使用这样的框架”时,我感到困惑。$
显然是一个外部库(jQuery),但JSON
是JavaScript的一部分。如果你还记得的话,那么对使用JSON
有什么顾虑呢?也许是因为在2010年,缺乏IE 6和7的支持? - ruffinJSON.stringify
在OP失败的具体原因。 - ruffin