我假设我在这里做了一些非常愚蠢的事情。我基本上有一个我传入函数的数组。我想删除该数组的一个元素并为它做一堆东西,然后只要该数组中仍有成员,就迭代遍历数组的其余部分。当数组为空时,我想循环回来并再次运行原始数组。
但是,在使用array.shift()时,我遇到了一个奇怪的问题。它似乎正在影响错误的变量,如果这甚至是有道理的。
抽象示例如下:
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()也会影响untouchedArray吗?
我希望insideArray会丢失它的第一个成员,它被存储为" removedNumber"但为什么未受影响的阿瑞也失去了它的第一个成员?
修改
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
新编辑
虽然这个问题已经过时了,但我想我会用更清晰的方法更新来解决这个问题:
JSON.parse(JSON.stringify(obj))
将创建对象的副本。
答案 0 :(得分:3)
在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
但是这是因为+
运算符返回一个新的数字对象而b
绑定到这个新对象而不是旧的。
如果您需要制作副本,则必须明确地执行此操作。对于数组,解决方案是调用slice
方法不传递任何参数。
var b = a.slice(); // Makes a new independent copy of the array
答案 1 :(得分:1)
javascript是通过值语言传递的。请阅读此link以获取更多信息或谷歌。
在这种情况下,您应该克隆阵列。
试试这个
let insideArray = untouchedArray.slice();
答案 2 :(得分:1)
在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'