2

I'm assuming I'm doing something really dumb here. I basically have an array that I'm passing into a function. I want to remove an element of that array and do a bunch of stuff to it, and then iterate through the rest of the array as long as there are still members in that array. When the array is empty, I want to loop back and run through the original array again.

However, I'm running into a weird issue when using array.shift(). It seems to be affecting the wrong variable if that even makes sense.

Abstract example as follows:

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)

The console log output yields:

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

This is without any looping going on. Can someone explain why doing the shift() on the insideArray ALSO affects the untouchedArray??

I would expect that the insideArray would lose it's first member which is stored as "removedNumber" but why is the untouchedArray also losing it's first member?

EDIT

    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)

Yields:

 number in is: 1
 original before is 1
 modified before is 1
 original after  is 1
 modified after  is 2

NEW EDIT

Although this question is super old, I figured I would update with a much cleaner method to solve this question:

 JSON.parse(JSON.stringify(obj))

will create a copy of the object.

Ross van Zyl
  • 87
  • 1
  • 10
  • 4
    Because your "insideArray" is actually a reference on "untouchedArray". You will have to copy the elements to get a true copy of the variable. (see http://stackoverflow.com/questions/18829099/copy-a-variables-value-into-another) – synthomat Aug 12 '15 at 15:32
  • see edited post. The result of that function is that the "original" variable never changes. It remains as "1". Why is that? – Ross van Zyl Aug 12 '15 at 15:40
  • I thiiink, that primitive data types (numbers, strings) are copied but objects are referenced. At least it's how Java handles it. – synthomat Aug 12 '15 at 15:44
  • You might want to look into using the reduce() method of Arrays. – Silkster Aug 12 '15 at 16:33

3 Answers3

4

In Javascript objects are never copied. If you write

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

both a and b are just pointers to the same array object. Thus for example executing a.push(99) you will see the new element when dumping b too.

It seems that copies are done with immutable types like numbers or strings:

var a = 14;
var b = a;
b = b + 3;
console.log(a); // still 14

but this happens because the + operator returns a new number object and b is bound to this new one instead of the old one.

If you need to make a copy you must do that explicitly. For arrays the solution is calling the slice method passing no parameters.

var b = a.slice(); // Makes a new independent copy of the array
6502
  • 112,025
  • 15
  • 165
  • 265
1

javascript is pass by value language. read this link for more inforamtion or google it.

In this case, you should clone your array.

try this

let insideArray = untouchedArray.slice();
Community
  • 1
  • 1
  • That does seem to work. Although I used "var" instead of "let". I had a weird error when I tried "let". Why does this not apply to the second function listed? The "getOne" function? – Ross van Zyl Aug 12 '15 at 15:44
  • @RossvanZyl, if you use external source for javascript you should use this attribute for work in best case. ```` – Ali Movahedi Aug 12 '15 at 15:47
  • [JS does not have "pass by reference"](http://whatsthepointy.blogspot.com.es/2013/11/javascript-does-not-have-pass-by.html) – Oriol Aug 12 '15 at 15:47
  • Use var. Let isn't as supported as var, and will give you issues on FireFox. – Mike Aug 12 '15 at 15:49
1

In JS, assignments are done by value:

var a = 1,
    b = a; // 1 (by value)
a = 2;
b; // 1 (not modified)

However, in the case of objects, that value is a reference in memory. That means that if you modify a property of the object, you will see the change in all variables:

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'
Oriol
  • 274,082
  • 63
  • 437
  • 513