Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how is array updated & returned in JS function

Tags:

javascript

Am trying to add/remove elements from an array declared inside a function. I have been able to add or remove and access the updated array for the same.

For accessing the array I have used two different approaches.

  1. Have created an inner function which returns the array.
  2. Have returned the array from the main function and accessing the same using dot notation.

Here is my code:

function test() {
  let myArr = [];

  const getMyArr = () => myArr;

  const add = n => {
    myArr.push(n);
    return () => {
      myArr = myArr.filter(a => a !== n);
    };
  };


  return {
    myArr,
    getMyArr,
    add
  };
}

let myTestRun = test();


let remove3 = myTestRun.add(3);
let remove7 = myTestRun.add(7);
let remove8 = myTestRun.add(8);
console.log("myArr after insertion", myTestRun.myArr);
console.log("getMyArr() after insertion", myTestRun.getMyArr());
remove7();

console.log("myArr after removing", myTestRun.myArr); //still returns the old array without any modifications
console.log("getMyArr() after removing", myTestRun.getMyArr()); //returns the modified array. how? Why didn't it work before?

What I do not understand is why did myArr did not have any modifications and how come getMyArr() function has returned the updated value. I used to believe that both the myArr point to the same object. So, any modifications on the myArr should be reflected via both the approaches. Why am I wrong. What is the reason behind this different return values? Please explain.

like image 863
Imran Avatar asked Sep 22 '26 19:09

Imran


2 Answers

TL;DR: Because filter returns a new array.

The object returned by test and the local variable both are referencing the same array. Mutating the array (push, pop, splice etc) through either of the references will modify the array.

This is only up until the call to remove7(). The filter method returns a new array and myArr variable is now referencing this new array while myTestRun.myArr still references the old array created initially. If you log myTestRun.myArr === myTestRun.getMyArr() at every point, it will start returning false after remove7().

But, getMyArr() is still taking closure over the let myArr variable. So, it will always log whatever the variable is currently holding at that moment

Here are some similar questions which might make it clear:

  • Is JavaScript a pass-by-reference or pass-by-value language?

  • Does Javascript pass by reference?

  • Pass Variables by Reference in Javascript

  • Javascript by reference vs. by value

like image 55
adiga Avatar answered Sep 25 '26 09:09

adiga


You change the object reference of myArr, but you need the same object reference and for deleting, you could splice the unwanted elements.

function test() {
  let myArr = [];

  const getMyArr = () => myArr;

  const add = n => {
    myArr.push(n);
    return () => {
      var i = myArr.length;
      while (i--) if (myArr[i] === n) myArr.splice(i, 1);
    };
  };

  return { myArr, getMyArr, add };
}

let myTestRun = test();

let remove3 = myTestRun.add(3);
let remove7 = myTestRun.add(7);
let remove8 = myTestRun.add(8);
console.log("myArr after insertion", myTestRun.myArr);
console.log("getMyArr() after insertion", myTestRun.getMyArr());
remove7();

console.log("myArr after removing", myTestRun.myArr); //still returns the old array without any modifications
console.log("getMyArr() after removing", myTestRun.getMyArr()); //returns the modified array. how? Why didn't it work before?
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 39
Nina Scholz Avatar answered Sep 25 '26 08:09

Nina Scholz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!