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克隆“类”实例[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何克隆 javascript ES6 类实例

原型模式

java,,"浅克隆,只复制一个对象 ,深克隆 对象和引用一起复制"有java实例吗?不理解啊

浅谈Java中的克隆机制

Java 常用类库 之 对象的克隆 Cloneable

JavaScript中的克隆对象[重复]