为什么我的对象在数组更新时引用数组元素更新?

时间:2016-11-08 18:06:25

标签: javascript

我很困惑对象引用在Javascript中如何在数组方面工作,并且找不到针对此特定问题的任何相关材料。我有以下代码。我初始化一个名为arr的对象数组,并设置一个等于数组中第一个元素的新变量c。如果我更改数组元素,变量c也会按预期更改。因此我假设c是指向数组第一个元素的指针。

但是,如果我将arr完全设置为新数组,则变量c 不会更新。我希望它可以A)更新到变色龙'这是新数组的第一个元素,或者更可能是B)变得未定义。

在将c设置为等于新数组后,变量arr指向的对象是什么?它会成为自己的对象吗?

var arr = [{animal: 'cat'}, {animal: 'bear'}];
var c = arr[0];
console.log(JSON.stringify(c.animal));
// Prints 'cat'

arr[0].animal = 'iguana';
console.log(JSON.stringify(c.animal));
// Prints 'iguana'

arr = [{animal: 'chameleon'}, {animal: 'bear'}];
console.log(JSON.stringify(c.animal));
// Prints 'iguana' instead of 'chameleon'

5 个答案:

答案 0 :(得分:2)

c不是对arr的第一个元素的引用。它是对象的引用,该对象恰好位于arr中。无论arr发生什么情况,c都会继续引用该对象,除非您为c分配新值。

在结束前的第二行,您使用新值覆盖 arr变量。 c值仍然指向它已经执行的相同对象。用全新的值替换arr不会改变它。

  

将arr设置为等于新数组后,变量c指向的是什么对象?它会成为自己的对象吗?

在重新分配arr之前它指向的同一个对象。它没有改变。

另一个示范:



var arr = [{animal: 'cat'}, {animal: 'bear'}];
var c = arr[0];

console.log(c.animal);
// Prints 'cat'

// access the value in arr[0] and modify its `animal` property
arr[0].animal = 'iguana';
console.log(c.animal);
// Prints 'iguana'

// REPLACE the 0th element of arr with a new value
arr[0] = { animal: 'pig' };
console.log(c.animal);
// still prints 'iguana'




答案 1 :(得分:2)

实际上非常简单。 c并未指向arr[0] c指向存储在arr内的索引[0]的 对象 即可。即使重新分配arr,该绑定仍保持不变。换句话说,arr[0]是结束的手段 - 对存储在那里的对象。这就是c引用的内容,而不是关于如何实现它的说明。

现在,如果您在重新分配var c = arr[0];后再次运行arr行,c肯定会指向一个新对象,但您没有这样做。您只分配了c一次,因此它保留了对原始对象的引用。

这是一个非常简单的比喻。如果我把你介绍给我最好的朋友,我现在已经建立了你和那个人之间的关系(你认识他,因为你经历了我)。但是,如果我与那个人发生了激烈的争斗(即他们不再是我的朋友而且我不再与他们有任何关系),那么这并不会影响你认识那个人的能力。我只是向你介绍了两个,但引用的是你和他之间。

请记住,在JavaScript中将对象分配给变量(或属性)时,您要为该对象分配“引用”,而不是对象本身。

答案 2 :(得分:1)

我认为你混淆的原因是你在思考其他语言,比如c,它使用指向内存中特定值的指针。在javascript中,数组和对象变量存储对实际数组/对象的引用,而不是数组/对象本身。重新分配引用时,原始数组/对象不会被覆盖,而是将引用更改为指向另一个对象,也在内存中。

由于这些原因,在您的示例中,重新分配给arr将更改引用,指向内存中的新数组。但是,未重新分配的c仍将引用原始数组中的同一对象,该数组也仍在内存中。

希望这是有道理的。

答案 3 :(得分:0)

始终要知道如何传递价值观:

http://docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm

答案 4 :(得分:0)

您正在重新分配arr指向的整个数组(引用) - 它是一个全新的引用。变量c指向与之前相同的引用,因为您没有更改c的引用。