Javascript 使用array.shift()会影响错误的变量
我想我在做一些很愚蠢的事情。我基本上有一个数组,我将它传递到一个函数中。我想删除该数组的一个元素,并对其执行一系列操作,然后遍历该数组的其余部分,只要该数组中还有成员。当数组为空时,我想返回并再次运行原始数组 但是,在使用array.shift()时,我遇到了一个奇怪的问题。如果这有意义的话,它似乎影响了错误的变量 抽象示例如下:Javascript 使用array.shift()会影响错误的变量,javascript,arrays,Javascript,Arrays,我想我在做一些很愚蠢的事情。我基本上有一个数组,我将它传递到一个函数中。我想删除该数组的一个元素,并对其执行一系列操作,然后遍历该数组的其余部分,只要该数组中还有成员。当数组为空时,我想返回并再次运行原始数组 但是,在使用array.shift()时,我遇到了一个奇怪的问题。如果这有意义的话,它似乎影响了错误的变量 抽象示例如下: var originalArray = [1,2,3,4,5,6,7,8,9] function goThroughArray(array){ var
var originalArray = [1,2,3,4,5,6,7,8,9]
function goThroughArray(array){
var untouchedArray = array
console.log('untouched array before is ' + untouchedArray)
var insideArray = untouchedArray
console.log('inside array is ' + insideArray)
var removedNumber = insideArray.shift()
console.log('removed number: ' + removedNumber + ' from insideArray')
console.log('inside array after is ' + insideArray)
console.log('untouched array after is ' + untouchedArray)
}
goThroughArray(originalArray)
控制台日志输出产生:
untouched array before is 1,2,3,4,5,6,7,8,9
inside array is 1,2,3,4,5,6,7,8,9
removed number: 1 from insideArray
inside array after is 2,3,4,5,6,7,8,9
untouched array after is 2,3,4,5,6,7,8,9
这是没有任何循环的。有人能解释为什么在insideArray上执行shift()也会影响未触及的Darray吗
我希望insideArray会丢失它的第一个成员,该成员被存储为“removedNumber”,但为什么未触及的Darray也会丢失它的第一个成员
编辑
function addOne(number){
console.log('number in is: '+number)
var original = number;
var modified = original
console.log('original before is ' + original)
console.log('modified before is ' + modified)
modified++
console.log('original after is ' + original)
console.log('modified after is ' + modified)
}
addOne(1)
收益率:
number in is: 1
original before is 1
modified before is 1
original after is 1
modified after is 2
新编辑
function addOne(number){
console.log('number in is: '+number)
var original = number;
var modified = original
console.log('original before is ' + original)
console.log('modified before is ' + modified)
modified++
console.log('original after is ' + original)
console.log('modified after is ' + modified)
}
addOne(1)
虽然这个问题非常古老,但我想我会用一个更干净的方法来解决这个问题:
JSON.parse(JSON.stringify(obj))
将创建对象的副本。javascript是传递值语言。阅读此文了解更多信息,或用谷歌搜索 在这种情况下,您应该克隆阵列 试试这个
let insideArray = untouchedArray.slice();
在JS中,赋值是按值完成的:
var a = 1,
b = a; // 1 (by value)
a = 2;
b; // 1 (not modified)
但是,对于对象,该值是内存中的引用。这意味着,如果修改对象的属性,将在所有变量中看到更改:
var obj1 = {},
obj2 = obj1;
obj1.foo = 'bar';
obj2.foo; // 'bar' (the change is reflected in the other variable)
obj1 = {}; // However, if you replace the entire object, the change
// won't be reflected because assignments are done by value
obj1.foo; // undefined
obj2.foo; // 'bar'
在Javascript中,对象永远不会被复制。如果你写信
var a = [1, 2, 3, 4];
var b = a;
a
和b
都只是指向同一数组对象的指针。因此,例如执行a.push(99)
时,您也会在转储b
时看到新元素
似乎复制是使用不可变的类型(如数字或字符串)完成的:
var a = 14;
var b = a;
b = b + 3;
console.log(a); // still 14
但是发生这种情况是因为+
操作符返回一个新的number对象,并且b
绑定到这个新对象而不是旧对象
如果你需要复制,你必须明确地这样做。对于数组,解决方案是调用slice
方法,不传递任何参数
var b = a.slice(); // Makes a new independent copy of the array
因为你的“insideArray”实际上是“未接触Darray”的参考。您必须复制元素才能获得变量的真实副本。(请参阅)请参阅编辑的帖子。该函数的结果是“原始”变量永远不会更改。它仍然是“1”。这是为什么?我认为,原语数据类型(数字、字符串)被复制,但对象被引用。至少这是Java处理它的方式。您可能希望研究使用数组的reduce()方法。这似乎确实有效。虽然我用了“var”而不是“let”。当我尝试“让”时,我犯了一个奇怪的错误。为什么这不适用于列出的第二个函数?“getOne”函数?@RossvanZyl,如果您对javascript使用外部源代码,那么您应该在最佳情况下使用此属性
使用var。Let没有var那么受支持,它会给您在FireFox上带来问题。这是有道理的。我想我从来都不知道javascript是如何处理对象和内存的。谢谢