skip to Main Content

I do understand there are other ways of doing this, so I don’t need a different solution, I just want to understand why this happens!

While working on something else I came across an issue addressing arrays from a function which I don’t understand, so I made a simple version to look at the issue.

const origionalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

const removeElementByIndex = function(ind, arr) {
  let j = 0, tmpArr = [];
  for (let i=0; i<arr.length; i++) {
    if (i !== ind) {
      tmpArr[j] = arr[i];
      j++;
    };
  };
  
  arr.splice(0, arr.length);
  console.log(origionalArray, arr,  tmpArr);
  arr = [...tmpArr];
  console.log(origionalArray, arr, tmpArr);
};

removeElementByIndex(4, origionalArray);

As you can see the funciton takes two arguments, the name of the array and the index of an element to be removed. (Yes, I do know arrayName.splice(index, 1); will achieve the same result) puts the elements that should remain in the origional array into a temp array, clears the origional array, then attempts to populate the origional array with the values from the temp array:

And here is the problem I don’t understand.

arr.splice(0, arr.length); does clear the array (both arr withing function and origioanlArray
but
arr = [...tmpArr]; ONLY populates arr within the function! origionalArray is uneffected

why is one line effecting the origionalArray and another not?

It obviously isn’t a scope issue and using splice alone in the fuction instead does work, and that is probably why I am confused.

const origionalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

const removeElementByIndex = function(ind, arr) {
  arr.splice(ind, 1);
};

removeElementByIndex(4, origionalArray);
console.log(origionalArray);

I do have ways around the problem as I said, but I was expecting origionalArray to be populated and don’t undestandy why it isn’t occurring.

2

Answers


  1. The problem that arr = [...tmpArr] just overwrites the argument passed, not the original variable passed as the argument.
    To change the original array you should mutate the original array:

    const origionalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    const removeElementByIndex = function(ind, arr) {
      let j = 0, tmpArr = [];
      for (let i=0; i<arr.length; i++) {
        if (i !== ind) {
          tmpArr[j] = arr[i];
          j++;
        };
      };
      arr.length = 0;
      arr.push(...tmpArr); // mutate, not overwrite the local argument variable
    };
    
    removeElementByIndex(4, origionalArray);
    console.log(JSON.stringify(origionalArray));
    Login or Signup to reply.
  2. When you call a function like this:

    removeElementByIndex(4, origionalArray);
    

    "origionalArray" is passed as an argument to the parameter "arr" in the function. This means that within the function, "arr" refers to the same array object as "origionalArray".

    In JavaScript, arrays are passed by reference. This means that both "arr" and "origionalArray" point to the same memory location where the array data is stored.

    Therefore, if you modify "arr" inside the function by doing this:

    arr.splice(0, arr.length);
    

    you are directly modifying "origionalArray".

    If you were to do something like:

    arr = [...tmpArr];
    

    this line does not change "origionalArray"; instead, it reassigns "arr" to a new array created from "tmpArr". After this line, "arr" no longer points to "origionalArray"; it now points to a new array, so "origionalArray" is unaffected.

    If you want "origionalArray" to be populated, do this:

    const origionalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    const removeElementByIndex = function(ind, arr) {
      let j = 0, tmpArr = [];
      for (let i=0; i<arr.length; i++) {
        if (i !== ind) {
          tmpArr[j] = arr[i];
          j++;
        };
      };
      
      arr.splice(0, arr.length);
      console.log(origionalArray, arr,  tmpArr);
      arr.push(...tmpArr);
      console.log(origionalArray, arr, tmpArr);
    };
    
    removeElementByIndex(4, origionalArray);

    or this:

    const origionalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    const removeElementByIndex = function(ind, arr) {
      let j = 0, tmpArr = [];
      for (let i=0; i<arr.length; i++) {
        if (i !== ind) {
          tmpArr[j] = arr[i];
          j++;
        };
      };
      
      arr.splice(0, arr.length);
      console.log(origionalArray, arr,  tmpArr);
      for(let i=0; i<tmpArr.length; i++){
        arr.push(tmpArr[i]);
      }
      console.log(origionalArray, arr, tmpArr);
    };
    
    removeElementByIndex(4, origionalArray);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search