使用array.shift()会影响错误的变量

时间:2015-08-12 15:29:47

标签: javascript arrays

我假设我在这里做了一些非常愚蠢的事情。我基本上有一个我传入函数的数组。我想删除该数组的一个元素并为它做一堆东西,然后只要该数组中仍有成员,就迭代遍历数组的其余部分。当数组为空时,我想循环回来并再次运行原始数组。

但是,在使用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))

将创建对象的副本。

3 个答案:

答案 0 :(得分:3)

在Javascript中永远不会复制对象。如果你写

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

ab都只是指向同一个数组对象的指针。因此,例如执行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'