JavaScript function return confusion

I’m going through one of the exercises and I got it working but I’m a bit confused.

So in the code below:

        function nextInLine(arr, item) {
            arr.push(item); 
            return arr.shift();  // Change this line
            }

            // Test Setup
            var testArr = [1,2,3,4,5];
            
            // Display Code
            console.log("Before: " + JSON.stringify(testArr));
            console.log(nextInLine(testArr, 6)); // Modify this line to test
            console.log("After: " + JSON.stringify(testArr));

I get why the first two console.logs work,

  1. Returns the stringified version of the original array.
  2. Returns the return value of the function.
  3. This is where I’m lost, the end result of what the array is returned ( [2,3,4,5,6]) but, it’s returning the var test Arrr.
    I thought when you returned a function it only returned into the calling item, not modified the data being used in the arguments.
    I’m not grasping how the var testArr was modified.

Array.shift() returns the removed element, not the modified array. Everything in the function was working on the same array. Think of it being passed as a reference or a pointer, not a copy of the object. You’d have to manually create a new array in the function to make it behave as pass-by-copy.

Just to further clarify…

It’s true that values sent to functions as parameters are not changed. And this works normally with all primitive types. The confusions comes with non-primitive types, names objects, of which arrays are in JS. In this case the parameter still is not changed, but you have to understand that what is being passed to the function is not the data itself but the address of that data structure. So while that address remains unchanged, you operated on the data in that memory location.

Consider the following code:

var x = 1

function double(num) {
  num = num * 2;
}

console.log('x before =', x)
// x before = 1
double(x)
console.log('x after =', x)
// x after = 1

//*************

var arr = [1, 2, 3]

function makeBigger(anArr) {
  anArr.push(4, 5, 6)
}

console.log('arr before =', arr)
// arr before = [1, 2, 3]
makeBigger(arr)
console.log('arr after =', arr)
// arr after = [1, 2, 3, 4, 5, 6]

In the first case, JS makes a copy of that data and operates on that copy so the original is not changed. That makes sense.

In the second example (because it is an object/array) JS is making a copy of the address. So, the function has the address and goes to that data location and makes changes to what is in that location. The address that it receives remains unchanged, but there was still only one copy of the data. There are ways to make actual copies, but we can worry about that another day - for now just understand why copies of the data aren’t being made.

This is an important concept with objects and will come into play when you try to copy objects. Simply copying the object creates a copy of the address so now instead of two copies of the data, you have variables that point to the same data and changing one will affect the other because they are pointing at the same location.

I know this is a little weird. I don’t know if I’ve gotten all of the terminology right - my understanding of this comes from programming classes in C many years ago. In C, this all becomes really clear really fast because you are actually manipulating addresses and data. In JS, this is hidden from you so it may take a while to sink in.

1 Like

I better understand the exercise / the concept after reading your example. I don’t understand how it applies to the exercise they gave us though. This is the solution with my comments

function nextInLine(arr, item) {

arr.push(item); // push the item where?
var removed = arr.shift(); // shift the item where?
return removed; // How does the function know it’s being sent to the array in var testArr?
}

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

// Display Code
console.log("Before: " + JSON.stringify(testArr));
console.log(nextInLine(testArr, 6)); // Modify this line to test
console.log("After: " + JSON.stringify(testArr));

Oh, now I understand. Thank you.

Thanks. I understand better now. I did some digging on MDN and couldn’t find anything that really explained how it worked.