splice正在影响以前复制的变量

时间:2013-01-05 08:52:26

标签: javascript

  

可能重复:
  Copying array by value in 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的故意行为还是个bug?

,其次,如何复制数组并删除副本中的元素但不能删除原始元素?

有一件事让我觉得以上可能是一个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,因为这个分配可能是通过引用来的吗?

3 个答案:

答案 0 :(得分:10)

这绝不是一个错误,而是一个非常普遍的误解。让我们看看当我说

时会发生什么
var a = b;

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

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

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

b a 可以互换。他们引用相同的内存地址。要实现您的目标,请使用

var copy_initial_variable = initial_variable.slice(0);

阅读Does JavaScript pass by reference?了解详情。

答案 1 :(得分:3)

在第一种情况下,您正在使用通过引用传递的数组。在第二种情况下,您正在使用按值传递的素数类型。在第一种情况下,您应该复制初始数组(例如,使用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);
};

答案 2 :(得分:0)

问题不在于splice的行为方式,而是initial_variablecopy_initial_variable引用相同数组的事实。

alert (copy_initial_variable === initial_variable);

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

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