iamrkcheers
iamrkcheers

Reputation: 413

Modifying an array in a function to which it is passed

function nextInLine(arr, item) {
  arr.push(item);
  var removedItem = arr.shift();
  return removedItem;
}

// Test Setup
var testArr = [1,2,3,4,5];

// Display Code
console.log("Before: " + JSON.stringify(testArr));
console.log(nextInLine(testArr, 6));
console.log("After: " + JSON.stringify(testArr)); //*THIS LINE HERE*

In the above code snippet, why is it that the 3rd console.log line prints [2,3,4,5,6] .. as per my logic, when testArr is passed to the nextInLine function, only a copy of testArr is passed as an argument. Thus, the 3rd console.log line must print [1,2,3,4,5] as it is, without any change!

Any help is appreciated. Thank You.

Upvotes: 1

Views: 105

Answers (4)

Rahul Arora
Rahul Arora

Reputation: 4533

In JavaScript, objects are passed by reference. Array is an object as well.

So while you are passing array to the function, it is actually passing a reference to the outer array which then gets modified.

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

var b = a;

b[0] = 2;

console.log(a); // outputs [2,2,3,4,5]

Here, editing b will actually edit update a as b is pointing to the memory location of a

Upvotes: 2

kabirbaidhya
kabirbaidhya

Reputation: 3490

As everyone here already mentioned that all objects in javascript (including Arrays) are passed by reference in functions. So, when you pass testArr into nextInLine function, the function will mutate the original array with the statement arr.push(item);.

However, if you want to prevent this you may either pass a copy/clone of testArr into the function. The easiest way to make a copy of array is like this:

var testArr = [1,2,3,4,5];
var copyOfTestArr = testArr.slice(0);

Alternatively, you can make the nextInLine function immutable by not mutating the original arguments like this:

function nextInLine(arr, item) {
  var removedItem = arr.concat([item]).shift();

  return removedItem;
}

// Test Setup
var testArr = [1, 2, 3, 4, 5];

// Display Code
console.log("Before: " + JSON.stringify(testArr));
console.log(nextInLine(testArr, 6));
console.log("After: " + JSON.stringify(testArr)); // *THIS LINE HERE*

Now, if you test this new function you should get the expected output.

Upvotes: 0

Rax Weber
Rax Weber

Reputation: 3780

In JavaScript, if you do this: var x = y where y is an Object, x is now a pointer to y. So, if you do this: x.foo = 5, y would also have foo equal to 5. But, if you do this: x = 10, it wouldn't affect y, because you are assigning a new value to x.

Also note that an Array is an Object in Javascript, so that explains your situation. More example (similar to your case):

var y = [];
var x = y;
x.push(5);
console.log(x); [5]
console.log(y); [5]
x = 10;
console.log(x); 10
console.log(y); [5]

For more details, check this SO answer.

Upvotes: 0

gauravmuk
gauravmuk

Reputation: 1616

JavaScript is pass-by-reference when you send an array or object. Ref: Is JavaScript a pass-by-reference or pass-by-value language?

To solve your issue, nextInLine(testArr.slice(), 6) would create a copy of the array.

Upvotes: 0

Related Questions