为什么将array.splice()用于变量的副本时会更改变量?

时间:2019-01-28 16:44:31

标签: javascript arrays

更改引用中的变量时,字符串和数组的行为会有所不同。

我很好奇为什么会这样,因为它使我非常困惑。

我在弄乱JavaScript,发现一些我不完全了解的东西。

让我说一个变量。 var a = 'Hello';

然后,我通过引用“ a”变量来创建一个新变量。 var b = a;

现在,我更改b变量。 b = 'World';

“ a”变量仍为“ Hello”。 console.log( a ) // 'Hello'

但是,如果我将“ a”变量设置为数组,并再次在“ b”变量中引用它,那么现在更改“ b”变量也会更改“ a”变量。

var a = [ 'Hey', 'There', 'Buddy' ];
var b = a;

b[1] = 'Where?';

console.log( a ) // [ 'Hey', 'Where?', 'Buddy']

在所示示例中,为什么数组的行为不同于字符串和其他数据类型?

6 个答案:

答案 0 :(得分:2)

因为b不是副本,所以它是一个指针。数组是相同的(只有一个实例)。

复制数组的一种方法是完全切片(从索引0的第一个元素开始)。

var b = a.slice(0);

另请参阅:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

答案 1 :(得分:1)

  

为什么数组的行为与字符串和其他数据类型不同   显示的示例?

这是因为javascript中的字符串是按值传递或复制而不是引用。而数组是通过引用传递的。

假设您有:

 var a = "Hello":
 var b = a;

变量a的值已复制到变量b

但是当您这样做时:

var a = [ 'Hey', 'There', 'Buddy' ];
var b = a;

您只需将数组a的引用传递给b。因此,a和b都指向相同的参考。因此,其中任何一个所做的更改都会反映在其他方面。

基本上,您的内存中包含以下内容:

a:ref12344−−−+
             |
             |
             |    +−−−−−−−−−−−−−+                 
             +−−−>|  Array      |                 
             |    +−−−−−−−−−−−−−+                 
             |    | String      |         
             |    | String      |
b :ref12345−−+    |             |       
                  |             |
                  +−−−−−−−−−−−−−+

答案 2 :(得分:0)

它们的行为有所不同,因为String是按值引用的。另一方面,Array是指针引用,并且是对任何一个变量的“镜像”修改。

如果要生成数组的克隆,请通过创建新的数组来完成:

var old = [1, 2, 3];
var ref = old;       // <-- ref still points to "old"
var copy = [...old]; // <-- not a reference any longer

答案 3 :(得分:0)

因为您只是指向数组的引用。 var b并不是“持有”该数组,而是指向该数组的初始化位置,该位置仍为var a

答案 4 :(得分:0)

在Java语言中,原始类型(数字,字符串ecc ...)通过值传递,但是当您触摸对象(对于数组相同)时,它会通过引用传递。

var a = 2;
var b = a;
b = b - 1;
console.log(a,b)

var c = {
  a: 2
  }
var d = c;
d.a = d.a -1;
console.log(c, d)

答案 5 :(得分:0)

在JavaScript中,数组对象引用类型。这意味着,当为变量分配数组或对象时,分配给该变量的是对内存中存储数组或对象的位置的引用,而不是对象/数组本身的内容。

但是,与某些语言相反,字符串是JS中的值类型,而不是数组,它们在分配和复制时的行为类似于number,boolean,null和undefined。

splice方法不会生成新的数组,它会根据给定的参数变异该数组,因此引用该相同数组的每个其他变量也将看到更改。

如果您希望您的源数组保持不变,请改用slice方法,该方法不可变。它将制作一个副本,对该副本进行变异并返回。