这是一些琐碎的小问题,其中没有任何问题尚未(这一点越来越令人惊讶,我想的就越多)但是无论如何困扰我,我不能似乎在其他地方找到了足够的答案。
假设我有两个例子
示例1
var foo = [1,2],
bar = foo;
bar[0] = 9;
console.log(foo, bar);
这将输出[9,2] [9,2]。
示例2
var foo = [1,2],
bar = [1,2];
bar[0] = 9;
console.log(foo, bar);
这将输出[1,2] [9,2]。
从技术角度来看,示例1 和示例2 之间的区别是什么?
在示例一中,看起来您正在将bar初始化为foo的值,但仅更改bar的值。为什么示例1 中的bar [0] = 9也会更改存储在foo中的值?
另一方面,如果我想做到这一点怎么办?假设我无法知道foo在运行时的价值是什么,但是想要以与foo相同的值初始化bar,然后稍后更改bar的值并且只禁止我如何去做?
答案 0 :(得分:2)
在示例1中,没有值复制,但您将foo
的引用分配给变量bar
。
现在它们都指向同一个对象(数组,位于相同的内存位置),因此当您更改其中一个数组项时,它会更改两个变量指向的相同内存位置到。
要回答底部的问题,您需要复制/克隆foo
,然后将该克隆(将是一个新的对象实例)分配给bar
。然后,您将处于示例2中的情况,您可以在其中单独更改它们。
答案 1 :(得分:0)
该行
bar = foo;
相当于说“bar指向与foo相同的东西”
虽然将它们分配给[1,2],但它们都指向不同的元素,因此你可以修改一个而不用另一个。
如果你想在不改变foo的情况下修改bar,你应该使用:
var foo = [1,2];
var bar = foo.slice(0);
答案 2 :(得分:0)
Javascript中的数组是引用类型。
在示例一中,您有一个数组,其中有两个变量指向它。 如果访问两个变量中的任何一个,则将更新基础数组。记录时,它与您正在记录的阵列相同。
在示例二中,有两个数组,每个数组都有一个指向它的变量。当您访问变量时,它将访问相应的数组。
如果要在不引用同一数组的情况下基于前一个数组初始化新数组,则需要复制变量:
var foo = [1, 2],
bar = [];
for (var i = 0; i<foo.length;i++){
bar.push(foo[i]);
}
// or a shortcut:
bar = foo.slice(0);
这适用于Arrays,也适用于JS中的任何对象。对于对象,如果您还想复制所有子对象,则称为cloning
(或deep-cloning
。