是jQuery´;s是否扩展在对象之间创建引用?
我正在用枪法伸出手。扩展后,为什么修改快照会改变shat是jQuery´;s是否扩展在对象之间创建引用?,jquery,object,reference,extend,Jquery,Object,Reference,Extend,我正在用枪法伸出手。扩展后,为什么修改快照会改变shat var shat = [{bang:true}, {bumm: false}, {bong: false}] var shot = [{bang:false}, {bumm: false}, {bong: false}] $.extend(shat, shot) shot[0].bang = true console.log("shat", shat) // prints Object bang: true // why is t
var shat = [{bang:true}, {bumm: false}, {bong: false}]
var shot = [{bang:false}, {bumm: false}, {bong: false}]
$.extend(shat, shot)
shot[0].bang = true
console.log("shat", shat)
// prints
Object
bang: true // why is this true?
Object
bumm: false
Object
bong: false
我假设创建了一个引用,或者由于某种原因,扩展发生在快照[0]之后。bang=true。问题是,我想在扩展后修改快照,但当然不想对shat产生任何影响。你知道为什么会发生这种情况吗?我能做些什么来避免这种情况
请参阅JSFIDLE测试用例:有趣的是,它可以工作,但不知道
extend
可以在阵列上工作
原因是这两个数组都包含对同一对象的引用。这与警告“新建”的原因相同:
这两个变量都引用了同一个对象,因此编辑该对象会更新它们都引用的对象。从jQuery文档中,看起来$.extend只对对象进行扩充,而不对数组进行扩充。在本例中,您的
shat
变量从未更改。Extend只会覆盖属性(如果使用了键):
var a = {
hello: "kitty"
},
b = {
hello: "world"
}
$.extend( a, b );
console.log( a );
//Object
//hello: "world"
因为数组只是具有数字属性名的对象,所以您将使用相同的原则替换它们,除了“hello”
是“0”
等等
由于您使用的是对象而不是基本体,
shat
获取shot
的对象,因此它们会被重写,从而丢失原始的shat
对象。因此,修改shot
的对象将修改shat
的对象,因为它们是相同的对象。默认情况下,$。extend
只是浅拷贝属性*。这不太令人兴奋
在这种情况下,扩展的属性是“0”、“1”、“2”等,因此扩展后的shat[0]===shot[0]为真,这仅在两个属性对同一对象求值时才是真的。既然他们是同一个物体。。。在一个地方变异,在任何地方都会变异
将它们分开,考虑一个“深度副本”(参见调用的不同方法)。我提到的另一种方法,因为它也可以在其他上下文中使用,就是序列化对象,然后反序列化它——例如,使用JSON
var shat = [{bang:true}, {bumm: false}, {bong: false}]
var shot = [{bang:false}, {bumm: false}, {bong: false}]
$.extend(true, shat, shot) // use "deep copy"
shat[0] === shot[0] // false; different objects now so...
shot[0].bang = "boom" // ...this will not affect the object named by shat[0]
shot[0].bang // "boom"
shat[0].bang // false
快乐编码
*也就是说,对于源对象中的每个属性,
p
,它只执行target[p]=source[p]
。请记住,在JavaScript中,数组只是一种特殊的对象子类型,具有神奇的长度:索引n处的值由属性“n”命名。好的,我知道了,但我没有做类似于a=b或shat=shot的事情内部extend
正在做类似于shat[0]=shot[0]
的事情。但是,shat[1]==shot[1]这也是事实。如何解释呢?@GraceShao所有的shat[x]===shot[x]
都是这样,其中x
是一个扩展属性:我搞砸了,正如我应该说的那样,“1”和“2”也被复制了:)你的回答非常正确:它对数组没有特殊的处理。但是,shat
和shot
仍然是两个不同的对象:来自shat
的属性刚刚被来自shot
的属性扩充(覆盖)。这有点道理:-),现在,我想理解为什么在执行类似于here@Marcel的操作时没有任何问题,因为复制的属性值是不可变的——因此即使它们是===
,没有办法对它们进行变异:)请记住,shot
和shat
命名两个单独的对象,以便对其中一个对象进行变异(为属性指定不同的值)不会影响另一个对象。在最初的帖子中,一个共享对象发生了变异(即:{bang:false}
);var x={};变量y={a:a};x、 a=y.a;y、 a.v=“bar”代码>那么这些都是真的:a==x.a
,a==y.a
,和,a.v==bar
。(名为a
的对象发生了变异:上面只创建了一个属性为“v”的对象。)
var shat = [{bang:true}, {bumm: false}, {bong: false}]
var shot = [{bang:false}, {bumm: false}, {bong: false}]
$.extend(true, shat, shot) // use "deep copy"
shat[0] === shot[0] // false; different objects now so...
shot[0].bang = "boom" // ...this will not affect the object named by shat[0]
shot[0].bang // "boom"
shat[0].bang // false