为什么复杂类型适用于参考值

时间:2014-07-25 15:19:56

标签: javascript complextype

这是一些琐碎的小问题,其中没有任何问题尚未(这一点越来越令人惊讶,我想的就越多)但是无论如何困扰我,我不能似乎在其他地方找到了足够的答案。

假设我有两个例子

示例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的值并且只禁止我如何去做?

3 个答案:

答案 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