11

可能重复:
在javascript中按值复制数组

我有一个有趣的 javascript 问题。我复制一个数组变量以仅对副本进行修改,然后拼接副本以删除一个元素。但是原始数组变量受拼接影响 - 就好像副本是“通过引用复制”:

window.onload = function() {
  var initial_variable = ['first', 'second', 'third'];
  var copy_initial_variable = initial_variable;
  copy_initial_variable.splice(0, 1);
  alert('initial variable - ' + initial_variable);
};
//output: initial variable - second,third

首先,这是 javascript 的故意行为还是错误?

其次,我怎样才能制作一个数组的副本并删除副本中的一个元素而不是原始元素?

让我认为上面可能是一个 javascript 错误的一件事是,这种行为只发生在数组而不是整数。例如:

window.onload = function() {
  var initial_variable = 1;
  var copy_initial_variable = initial_variable;
  copy_initial_variable = 2;
  alert('initial variable - ' + initial_variable);
};
//output: initial variable - 1

如果行为是一致的,那么这应该输出2,因为分配可能是通过引用?

4

3 回答 3

14

这绝不是一个错误,而是一个非常普遍的误解。让我们看看我说的时候会发生什么

var a = b;

整数和其他 javascript 原语,如浮点数和布尔值,是“按值分配的”。这意味着b具有的任何值都将被复制到a。对于计算机而言,这意味着将b引用的内存部分复制到 a 引用的内存。这就是您所期望的行为。

当像这样使用数组和其他对象(以及new Object()调用的“后代”)时,就会有一个引用副本。这意味着a的值现在引用 b 的值,b引用的内存 不会被复制或修改。因此,当写

a = [1,2,3];
b = a;

ba可以互换。他们引用相同的内存地址。要实现您想要做的事情,请使用

var copy_initial_variable = initial_variable.slice(0);

阅读JavaScript 是否通过引用传递?了解更多信息。

于 2013-01-05T09:05:37.550 回答
4

在第一种情况下,您正在使用通过引用传递的数组。在第二种情况下,您正在使用按值传递的素数类型。在第一种情况下,您应该复制初始数组(例如 with initial_variable.slice(0))。尝试类似的东西

window.onload = function() {
  var initial_variable = ['first', 'second', 'third'];
  var copy_initial_variable = initial_variable.slice(0); //returns new array!!!!
  copy_initial_variable.splice(0, 1);
  alert('initial variable - ' + initial_variable);
};
于 2013-01-05T09:01:10.460 回答
0

问题不在于splice行为方式,而在于initial_variableandcopy_initial_variable引用同一个数组这一事实。

alert (copy_initial_variable === initial_variable);

在 JavaScript 中有两种类型的值:原始值,如数字和布尔值,以及对象,包括数组。变量保存原始值,但它们保存对对象的引用。“复制”原始值按您的预期工作,创建一个新的原始值,以便更改copy变量不会更改原始变量。但是“复制”一个对象实际上复制了指向该对象的引用,它不会创建一个新对象。

不是JavaScript 错误,这是预期的行为。

于 2013-01-05T08:55:42.513 回答