浅克隆对象是什么意思?

时间:2012-06-03 08:48:32

标签: javascript underscore.js

我正在使用underscore.js库有一个克隆方法。

var newObject = _.clone(oldObject);

我从其中一条评论中读到,它是一个浅层克隆。我想复制一个对象并将其传递给不同的函数。

当我改变function A()内的newObject时,我得到以下结果......

{
    'Des': 'Some Des'
    'Des1': 4,
    'Des2': {
        "ChildDes": 0,

    },
},

但是当我将作为克隆对象的newObject传递给另一个function B()时,我得到的警报值为[Object,Object]。为什么?我无法打印这样的值..

function B(newObject){
   alert(newObject.Des2);
}

2 个答案:

答案 0 :(得分:4)

“浅拷贝”是一个副本,只复制所有成员。如果其中一个成员是对象的引用,则复制引用上的更改将影响原始对象。 “深层复制”也会复制对象,因此深度复制元素的更改不会影响原始对象。 深层副本有时很难实现,因为对象成员可以在对象本身上有引用。

使用不同的复制样式玩一点,看看会发生什么。另见:What does it mean to clone() an object?

答案 1 :(得分:0)

“浅拷贝”和“深拷贝”这两个术语并未一致使用,应避免使用恕我直言。我建议将克隆操作分为三类:

  1. 公共克隆方法的行为,其目的是保存各种对象(例如`SuperDuperList`)应该是创建一个原始类型的新实例,它保存与原始实例相同的实例,但是与它。对原始对象或克隆对象所做的任何事情都不应影响另一个对象存在的事物的身份。请注意,虽然`SuperDuperList`可能有一些类型为'T []`的私有字段,但`SuperDuperList`的目的不能保存`T的数组 `,而是保存`T`的实例。因此,“SuperDuperCollection”的正确克隆方法必须用新数组替换任何可变数组,这些数组与原始数据保持相同的“T”实例,但是与它们分离。有些人将这种类型的副本称为“浅拷贝”,但有些人将该术语用于下面的#2“破损副本”语义。有人称之为“深层复制”,但有些人 - 包括我自己 - 会将该术语限制为使用#3。我更喜欢术语“语义级复制”。
  2. 一些破碎的克隆方法使得原始对象和克隆对象都保持对共享对象的引用,该对象是从原始对象的角度来看的,是可变的。请注意,从`SuperDuperList`的角度来看,类型为“T”的存储位置不包含对可能可变对象`T`的引用,而是保存了一个`的不可变标识。 T`。另一方面,如果`SuperDuperList`有一个字段,其中包含对`T`数组的引用,并且该数组将永远变异,那么克隆方法会让原始对象和克隆对象都保持对它的引用数组将被打破。
  3. 一些克隆方法要求被克隆对象持有的对象必须符合某些特殊条件才能克隆它们(最典型的是,每个嵌套对象的每个属性必须是不可变的或提供克隆方法)。在某些情况下,这些对象的集合可能无法确切地知道对象是什么或它们的克隆方法实际上做了什么;如果集合的克隆操作的语义比其对存储在其中的对象的理解更深入,则这样的集合是可深度克隆的。

派生对象的克隆方法的正常模式应该是从克隆其父对象开始,然后克隆任何包含外部对象引用的字段,这些对象包含要克隆的对象应该保留的内容,哪些不能依赖永远持有那些相同的东西。如果每个派生类都遵循该模式,那么将实现适当的语义级克隆。