更改对象内的数组(反之亦然)会更改更改前后对该数组的所有引用

Changing an array within an object (and vice versa) changes all references to that array before and after the change

在JavaScript中,如果我定义一个数组,将该数组打印到控制台,然后更改数组,然后再次打印到控制台,这两次打印会出现不同。对象也一样。这对我来说很有意义-我第一次打印它,它还没有改变,第二次它已经改变了。

但是,通过测试我发现,如果我在数组中定义一个对象,打印它,更改对象,然后再次打印,两次打印将是相同的(它们都是更改后的版本)。类似地,如果我在 一个对象中定义一个数组 ,打印它,更改数组,然后再次打印,两次打印将是相同的(它们都是更改后的版本)。

我认为这可能与按引用或按值传递有关?但我不清楚如何在这里关联这个概念。一些我认为可能与我的回答有关的文章:

(所以)Is JavaScript a pass-by-reference or pass-by-value language?

(所以)Javascript by reference vs. by value

http://snook.ca/archives/javascript/javascript_pass

如果有人能帮忙解释一下,我将不胜感激。以下是我编写的测试,以举例说明我所询问的差异:

// Testing changing an array
// RESULT: Array console.logs are DIFFERENT before and after the change.
var arr123 = [1,2,3];
console.log(arr123);
arr123[0] = 4;
arr123[1] = 5;
arr123[2] = 6;
console.log(arr123);

// Testing changing an object
// RESULT: Object console.logs are DIFFERENT before and after the change.
var obj123 = {
    first: 1,
    second: 2,
    third: 3
};
console.log(obj123);
obj123.first = 4;
obj123.second = 5;
obj123.third = 6;
console.log(obj123);

// Testing changing an object inside of an array.
// RESULT: Array console.logs are THE SAME before and after the change, reflecting the change.
var arrOfAnObj = [
    {first: 1, second: 2, third: 3}
];
console.log(arrOfAnObj);
arrOfAnObj[0].first = 4;
arrOfAnObj[0].second = 5;
arrOfAnObj[0].third = 6;
console.log(arrOfAnObj);

// Testing changing an array inside of an object.
// RESULT: Object console.logs are THE SAME before and after the change, reflecting the change.
var objOfAnArr = {
    arr: [1, 2, 3]
};
console.log(objOfAnArr);
objOfAnArr.arr[0] = 4;
objOfAnArr.arr[1] = 5;
objOfAnArr.arr[2] = 6;
console.log(objOfAnArr);

在所有情况下,您都在修改初始对象,这仅与浏览器如何以及何时读取您通过它传递的对象有关 console.log()

说明

我在 this repl 中执行了你的代码,结果总是不同。

我在 chrome 中执行,我可以重现你的案例。所以它与浏览器何时读取您的变量有关。因为在前两种情况下,变量只有一个级别,所以 chrome 向您显示内联值,因此在记录时读取对象。

在最后两种情况下,您还有一个级别,因此 chrome 在您在控制台中展开对象时读取对象引用。

我还注意到 chrome 以不同方式显示您的日志,无论您是在开发工具打开时 运行 您的代码,还是在 之前 运行 您的代码 打开开发工具。

如果你在打开开发工具之前运行代码,你会得到以下输出:

而如果您在 运行 编写代码之前打开开发工具,您将得到以下输出: