jQuery 的扩展是否在对象之间创建引用?

发布于 2024-12-27 03:43:31 字数 564 浏览 1 评论 0原文

我用射击来延长距离。延长后,为什么修改镜头会改变效果?

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

我假设在 shot[0].bang = true 之后创建了一个引用或由于某种原因发生了扩展。问题是,我想在延伸后修改镜头,但当然不想对镜头产生任何影响。有什么想法为什么会发生这种情况以及我可以做些什么来避免这种情况吗?

请参阅 jSfiddle 测试用例: http://jsfiddle.net/yEnph/3/

I am extending shat with shot. After extending, why does modifying shot alter 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 this true?
Object
bumm: false
Object
bong: false

I am assuming a reference is created or the extending is for some reason happening after the shot[0].bang = true. The problem is, I want to modify shot after the extending, but of course dont want to have it any effect on shat. Any ideas why this is happening and what I could do to avoid that?

see jSfiddle testcase: http://jsfiddle.net/yEnph/3/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

玩心态 2025-01-03 03:43:31

默认情况下,$.extend 仅浅复制属性*。这不是很令人兴奋。

在本例中,扩展属性为“0”、“1”、“2”等,因此 shat[0] === shot[0] 为 true扩展后两者计算结果为相同对象时的情况。既然它们是同一个对象,那么……好吧,改变一个地方就会改变它各处

为了使它们分开,请考虑“深层复制”(请参阅​​调用 jQuery.extend 的不同方法)。我提到的另一种方法是序列化对象,然后反序列化它,因为它也可以在其他上下文中使用,例如使用 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”命名。

By default, $.extend merely shallow-copies properties*. It's not very exciting.

In this case, the extended properties are "0", "1", "2", etc, and thus shat[0] === shot[0] is true after extending which is only the case if both evaluate to the same object. Since they are the same object then ... well, mutating it one place mutates it everywhere.

To keep them separate consider a "deep copy" (see the different ways to invoked jQuery.extend). Another approach, that I mention because it can also be used in other contexts, is to serialize the object and then de-serialize it -- e.g. with 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

Happy coding.


*That is, for every property, p, in the source object(s), it merely does target[p] = source[p]. Remember that, in JavaScript, Arrays are just a special subtype of object with a magical length: the value at index n is named by the property "n".

不甘平庸 2025-01-03 03:43:31

从 jQuery 文档 http://api.jquery.com/jQuery.extend/ 中,它看起来 $.extend 只增加对象,而不增加数组。在示例中,您的 shat 变量从未更改过。

From the jQuery document http://api.jquery.com/jQuery.extend/, it looks like $.extend only does Object augments, but not Array. In the example, your shat variable has never been changed.

享受孤独 2025-01-03 03:43:31

有趣的是,它确实有效,但不知道 extend 适用于数组。

原因是这两个数组都包含对同一对象的引用。这与警告“新”的原因相同:

http://jsfiddle.net/yEnph/4/

var a = { test: "one"};
var b = a;

a.test="new";

alert(b.test);

两个变量都引用同一个对象,因此编辑对象会更新它们都引用的对象。

Interesting that that works at all, wasn't aware that extend worked on arrays.

The reason for this though is that the two arrays both contain a reference to the same object. It's the same reason that this will alert "new":

http://jsfiddle.net/yEnph/4/

var a = { test: "one"};
var b = a;

a.test="new";

alert(b.test);

Both variables have a reference to the same object so editing the object updates the object, which they both reference.

还如梦归 2025-01-03 03:43:31

如果获取了键,扩展只会覆盖属性:

var a = {
   hello: "kitty"
},

b = {
   hello: "world"
}

$.extend( a, b );

console.log( a );
//Object
//hello: "world"

因为数组只是具有数字属性名称的对象,所以您将用相同的原理替换它们,除了 "hello""0" , 等等。

因为你有对象而不是基元,所以 shat 获取 shot 的对象,它们被重写,因此原始 shat 对象丢失。因此修改 shot 的对象将会修改 shat 的对象,因为它们是相同的对象。

Extend just overwrites the properties if the keys are taken:

var a = {
   hello: "kitty"
},

b = {
   hello: "world"
}

$.extend( a, b );

console.log( a );
//Object
//hello: "world"

Because arrays are just objects with numeric property names, you will replace them with same principle except "hello" is "0", and so on.

Because you have objects instead of primitives, shat gets shot's objects, they are rewritten so the original shat objects are lost. So modifying shot's objects will modify shat's objects because they are the same objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文