JavaScript克隆“类”实例[重复]
Posted
技术标签:
【中文标题】JavaScript克隆“类”实例[重复]【英文标题】:JavaScript cloning a "class" instance [duplicate] 【发布时间】:2012-01-16 18:17:45 【问题描述】:我有一堂课是这样的:
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/
【问题讨论】:
我似乎无法复制这个,看看这个jsFiddle。 看看这个:***.com/questions/728360/… 我刚刚添加了一个指向 jsfiddle sn-p 的链接 另外,我对问题做了一些修改 正确的解决方案是重新设计算法以消除对深度复制的需求。深度复制是a)正确的噩梦,b)计算成本高,c)创建依赖于所有被深度复制的逻辑。深拷贝是一个难以解决的问题,应该通过使用浅拷贝来避免。 【参考方案1】:$.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。
【讨论】:
所以基本上jQuery的extend方法很傻。 @Raynos$.extend()
无法完全支持带有构造函数的对象,因为它不知道要使用什么参数。
使用什么参数无关紧要。他们需要做的就是一对一地复制对象属性。这很容易做到。
@Raynos 这并不是您需要做的全部,因为您拥有对象的所有属性,但原型不正确,它远非“克隆”。还是我错过了什么:)?
clone。忽略你必须做的大量边缘情况和黑魔法,克隆功能的核心真的很容易。主要问题区域是宿主对象和具有内部魔法的本地对象。哦,避免在深拷贝中循环引用。【参考方案2】:
您可以使用http://documentcloud.github.com/underscore/#clone 克隆对象,例如:
var cloned = _.clone(states[0]);
【讨论】:
这行不通。阅读您发布的链接:Any nested objects or arrays will be copied by reference, not duplicated.
以上是关于JavaScript克隆“类”实例[重复]的主要内容,如果未能解决你的问题,请参考以下文章