1

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.

kabirbaidhya
  • 3,264
  • 3
  • 34
  • 59
iamrkcheers
  • 373
  • 2
  • 7
  • 16
  • 3
    What makes you think that the array is copied when the function is called? That's not how JavaScript works. – Ted Hopp Jun 19 '17 at 03:19
  • 2
    Possible duplicate of [Is JavaScript a pass-by-reference or pass-by-value language?](https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – david Jun 19 '17 at 03:23

4 Answers4

2

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

kabirbaidhya
  • 3,264
  • 3
  • 34
  • 59
Rahul Arora
  • 4,503
  • 1
  • 16
  • 24
0

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.

gauravmuk
  • 1,606
  • 14
  • 20
  • In general programming terms, "Pass by reference" means that the function can modify the value of the outside variable, which is not possible in JS. All JS arguments are passed by value, but in the case of objects/arrays the value is a reference. – nnnnnn Jun 19 '17 at 03:24
  • that is what is happening in OP's case – gauravmuk Jun 19 '17 at 03:26
  • "Pass by reference" is not what is happening, because if the function said `arr = null` that would not affect the `testArray` variable at all. But the `arr` argument does receive a reference to the same object that `testArray` refers to so it can mutate *that* specific object. – nnnnnn Jun 19 '17 at 03:27
0

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.

Rax Weber
  • 3,730
  • 19
  • 30
0

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.

kabirbaidhya
  • 3,264
  • 3
  • 34
  • 59