我有一个类似这样的课程:
function Element(){
this.changes = {};
}
现在我有一个像这样的“类”的实例,el = new Element()
。这些实例存储在数组中,如elements.push(el)
。
此元素数组现在存储在一个对象中,然后将其推送到数组中states
。
现在有些情况下我需要其中一个元素的副本,所以我需要做一些像var cloned = $.extend(true, {}, states[0])
这样的事情。在这里,我假设我们正在克隆第一个州。
现在的问题是我得到的,state[1].elements[0]
仍然指向原始实例。因此,我对克隆对象所做的任何更改也正在改变原文。
陷入如此微不足道的问题是令人沮丧的......
这是我为测试它而创建的小提琴: http://jsfiddle.net/E6wLW/
答案 0 :(得分:4)
$.extend
只是克隆普通对象。如果对象有一个构造函数,那么它不会被克隆,只是被复制。
来自$.extend
来源:
if ( jQuery.isPlainObject(copy) /* ... */) {
// do the recursive $.extend call and clone the object
} else if ( copy !== undefined ) {
target[ name ] = copy;
// ^^^^^ just copy
}
因此$.extend()
会调用isPlainObject(el)
,这将返回false,因为el
有一个构造函数而不是克隆el
被复制。所以states[1].elements[0]
与states[0].elements[0]
是同一个对象,因为它没有被克隆。
如果我们修改您的示例:
function Element(){
this.changes = {};
}
var el = new Element(); // $.isPlainObject(el); <- false
// ...
成:
var el = { changes: {} }; // $.isPlainObject(el); <- true
// ...
它会正确克隆el
。见 HERE 。
答案 1 :(得分:1)
您可以使用http://documentcloud.github.com/underscore/#clone克隆对象,例如:
var cloned = _.clone(states[0]);