为什么复杂类型对引用值起作用



这是一个琐碎的小问题,还没有给我带来任何问题(我越想越惊讶),但无论如何都困扰着我,我似乎在其他任何地方都找不到足够的答案。

假设我有两个例子

示例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有什么区别?

在示例1中,看起来您将bar初始化为foo的值,但只更改了bar的值。为什么在示例1中bar[0] = 9也改变了存储在foo中的值?

另一方面,如果我想这样做呢?假设我无法知道foo在运行时的值但我想将bar初始化为与foo相同的值然后改变bar的值,并且只改变bar的值我该怎么做呢?

在例1中没有进行值复制,但是您将foo的引用赋值给变量bar

现在它们都指向相同的对象(数组,在相同的内存位置),因此当你改变其中一个中的数组项时,它会改变两个变量指向的相同内存位置。

要回答底部的问题,您需要在foo上复制/克隆,然后将该克隆(这将是一个新的对象实例)分配给bar。那么您就处于例2中的情况,您可以独立地更改它们。

bar = foo;

相当于说"bar指向与foo相同的东西"

当它们都赋值给[1,2]时,它们都指向不同的元素,所以你可以修改其中一个而不改变另一个。

如果你想修改bar而不改变foo,你应该使用:

var foo = [1,2];
var bar = foo.slice(0);

Javascript中的数组是引用类型。

在示例1中,您有一个数组,有两个变量指向它。如果访问两个变量中的任何一个,将更新底层数组。当你记录它的时候,它和你记录的数组是一样的。

在示例二中,有两个数组,每个数组都有一个指向它的变量。当你访问一个变量时,它将访问相应的Array。

如果你想在前一个数组的基础上初始化一个新的数组,而不引用同一个数组,你需要复制变量:

var foo = [1, 2],
    bar = [];
for (var i = 0; i<foo.length;i++){
    bar.push(foo[i]);
}
// or a shortcut:
bar = foo.slice(0);

这适用于数组,也适用于JS中的任何对象。对于对象,这被称为cloning(或deep-cloning,如果您还想复制所有子对象)。

相关内容

  • 没有找到相关文章