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

时间:2016-03-17 17:59:30

标签: javascript arrays object javascript-objects

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

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

我认为这可能与通过引用或通过值传递有关?但我不清楚如何将这个概念与此相关联。我认为有些文章可能与我的回答有关:

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

(SO)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);

1 个答案:

答案 0 :(得分:0)

在所有情况下,您正在修改初始对象,它只与浏览器读取您通过console.log()传递的对象的方式和时间有关。

说明

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

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

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

另外,我注意到,无论您在开发工具处于打开状态时运行代码,还是在打开开发工具之前运行代码,Chrome都会以不同的方式显示您的日志。

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

enter image description here

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

enter image description here