jQuery:object [property] .push()修改旧对象,如果使用jQuery.extend()创建新对象

时间:2011-11-24 11:24:23

标签: javascript jquery clone

考虑这个示例代码:

a={};
a['herp']=['derp'];

var b = jQuery.extend({}, a);
b['herp'].push('foo');
alert(a['herp']); //this produces message box with "derp,foo"

据我所知,var b = jQuery.extend({}, a);克隆一个对象(由John Resig作为mentioned),即创建一个与前一个属性相同的新对象。如果这是正确的,那么为什么b['herp'].push('foo');会修改a,如alert(a['herp']);所示?

jsFiddle示例:http://jsfiddle.net/M48tr/

2 个答案:

答案 0 :(得分:3)

我认为你应该这样做:

var b = jQuery.extend(true, {}, a);

在此处http://jsfiddle.net/M48tr/1/

这是因为该属性是一个数组,您需要深度克隆。正如文档中所写:

  

默认情况下,$ .extend()执行的合并不是递归的。如果一个   第一个对象的属性本身就是一个对象或数组,它将是   被第二个中具有相同键的属性完全覆盖   object.the值没有合并。但是,通过传递true   第一个函数参数,对象将以递归方式合并。

如果您不进行深层复制,b['herp']只包含对a['herp']

中数组的引用

如果属性不是此示例中的数组或对象,则情况会有所不同:

a={};
a['herp']='derp';

var b = jQuery.extend({}, a);
b['herp'] = 'foo';
alert(a['herp']);//alerts derp

alert(b['herp']);//alerts foo

在这里摆弄http://jsfiddle.net/M48tr/2

答案 1 :(得分:1)

您应该仔细阅读并使用谷歌。通常Shallow copy - 创建一个新的“副本”。但指向同一块内存(数据 - 变量,常量等)。因此表示原始对象的“同义词”。而现在重要的是 - 无论你改变哪一个,都会影响到两者。

Deep copy更耗时,因为原始对象数据的 所有 都会复制到新对象中。这两个对象具有相同的结构(而不​​是指向相同的结构)。但是更改只会影响其中一个对象。