2

I have a function that reverses an array:

function reverseArray(array) {
  for(let i = 0; i <= Math.floor(array.length / 2); i++) {
    let old = array[array.length - 1 - i];
    array[array.length - 1 - i] = array[i];
    array[i] = old;
  }
  return array;
}

and a function that creates an local scope array and push values in reversed order:

function reverseArr(arr) {
  let output = [];
  for(let i of arr) {
    output.unshift(i);
  }
  arr = output;
  return arr;
}

Suppose there is an element:

let arrayValue = [1, 2, 3, 4, 5];

If i invoke the first function with arrayValue as argument, arrayValue is changed:

reverseArray(arrayValue); // [5, 4, 3, 2, 1]
console.log(arrayValue); // [5, 4, 3, 2, 1]

However if i invoke the second function with arrayValue:

reverseArr(arrayValue); //[5, 4, 3, 2, 1]
console.log(arrayValue); //[1, 2, 3, 4, 5]

arrayValue is not changed even if i assigned the reversed value to the argument before return:

arr = output;

can someone explain me why?

thanks in advance.

9
  • 1
    I don't think unshift does what you think it does. Read developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. Commented Nov 13, 2020 at 19:08
  • 1
    See also here, which describes a better approach using push. Commented Nov 13, 2020 at 19:10
  • 2
    Does this answer your question? Javascript function not modifying array (reference?) Commented Nov 13, 2020 at 19:17
  • @RobertHarvey um.... unshift() is the correct thing to use here.... OP is reversing an array so it is appending to the front, your suggestion is adding it to the end..... So OP would get back the same array order since the loop is not going backwards.... Commented Nov 13, 2020 at 19:17
  • 1
    JS is pass-by-value, when you do arr = output you're only reassigning the local variable arr. You don't replace the array it used to reference nor do you affect the other variable (arrayValue) that still references that array. In your first example you're mutating that array directly. Commented Nov 13, 2020 at 19:25

3 Answers 3

4

Basically you take a new array with

let output = [];

and later you assign the new array to the parameter arr

arr = output;

Now you have two object references, one arr of the outer scope and a new one of output.

To overcome this, you need to keep the object reference of array. For getting a new content in an existing array, you could empty the array and push the values of the new array.

arr.length = 0;
arr.push(...output);
Sign up to request clarification or add additional context in comments.

Comments

2

When you do arr = output in reverseArr you are referring to a new array. In other words arrayValue in the outer context and arr refer to two different objects.

You cannot change the value of the variable the function is called with. If you have a reference to the object you can mutate it, but you cannot make the outside variable refer to another object.

Comments

1

Basically, your first function reverses the list in-place (i.e. operates on the list itself directly, without building a new list), while the second function reverses the list out-of-place, by building a new list which contents are the reverse of the original list.

When working in-place, the changes you do to array inside the function are directly applied to arrayValue.

The reason why arr = output does not work the way you intend is pretty much what the other answers refer to. Namely, arr and arrayValue are two different references ("pointers"). Initially, both arrayValue and arr "point to" the same array when the function is called. However, arr = output makes arr point to the newly built list output instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.