我对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
,因为这个分配可能是通过引用来的吗?
答案 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);
答案 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_variable
和copy_initial_variable
引用相同数组的事实。
alert (copy_initial_variable === initial_variable);
在JavaScript中,有两种类型的值:原始值,如数字和布尔值,以及对象,包括数组。变量包含原始值,但它们包含对象的引用。 “复制”原始值按预期工作,创建新的原始值,以便更改copy
变量不会更改原始变量。但是“复制”对象实际上会复制指向该对象的引用,但它不会创建新对象。
不一个JavaScript错误,这是预期的行为。