为什么当数组更新时,引用数组元素的n't是我的对象

Why isn't my object which references an array element updating when the array updates?

本文关键字:对象 我的 更新 数组 数组元素 引用 为什么      更新时间:2023-09-26

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

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

arr被设置为一个新的数组之后,变量c指向的对象是什么?它会成为自己的对象吗?

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'

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'

其实很简单。c不指向arr[0] c指向存储在arr 索引[0]处的对象。即使在重新分配arr时,该绑定也保持不变。换句话说,arr[0]是达到目的的手段——存储在那里的对象。这就是c所引用的内容,而不是关于如何获得它的说明。

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

这里有一个很简单的类比。如果我把你介绍给我最好的朋友,我现在已经在你和那个人之间建立了关系(你认识他是因为你通过我认识他)。但是,如果我和那个人大吵了一架(例如,他们不再是我的朋友,我也不再和他们有任何关系),这并不影响你了解那个人的能力。我只是简单地介绍了你们俩,但这是你和他之间的事。

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

我认为你困惑的原因是你在考虑其他语言,如c语言,它使用指针指向内存中的特定值。在javascript中,数组和对象变量存储对实际数组/对象的引用,而不是数组/对象本身。当一个引用被重新赋值时,原来的数组/对象不会被覆盖,而是被改变为指向一个不同的对象,也在内存中。

由于这些原因,在您的示例中,重新分配给arr将改变引用,指向内存中的新数组。但是,没有重新赋值的c仍然会引用原始数组中的相同对象,该数组也仍然在内存中。

希望你明白。

始终注意如何传递值:

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

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