2

I want to understand, when I send an globalArray as a parameter to a recursive function, and assign the same array (localArray) to the globalArray, how is the memory allocation happening in javascript. I know that each recursion will have it's own callstack, and it will have it's own copy of variables, but since I am passing a globalArray into the function, will a copy of the localArray be always stored as a new array in each callstack?

If I were to achieve the localArray as an incremental copy of the same localArray variable for each execution context, how would I be achieving that?

Please view the image and code snippet enter image description here

function testFunction(localArray){
    globalArray = localArray;
    if(itr < 5) {
        globalArray.push(1);
        itr++;
        testFunction(localArray);
    }
}

var globalArray = [1,2,3];

var itr = 0;

testFunction(globalArray);

[added later to this question]

But if I were to modify the code a bit where I were to make the localArray as null, the globalArray would still be holding data, if it was a value which was referred.

function testFunction(localArray){
    globalArray = localArray;
    localArray = null;
    if(itr < 5) {
        globalArray.push(1);
        itr++;
        testFunction(globalArray);
}
}

var globalArray = [1,2,3];

var itr = 0;

testFunction(globalArray);

enter image description here

Sai Kumar
  • 201
  • 2
  • 8
  • 6
    Passing an array as a parameter does not make a copy of the array, nor does a simple assignment as in your function. There is only one array involved in your code. – Pointy Jan 25 '22 at 15:24
  • 1
    To develop Pointy's comment, arrays are a reference type in JavaScript. What you are passing around here is a reference, not the array itself. – Will Alexander Jan 25 '22 at 15:28
  • @WillAlexander can you have a look at my latest edits to this question, and explain me where am I getting it wrong in my understanding? If it was a pass by reference, then if I were to change value of one or the array, it would impact the other variable holding the array, correct? – Sai Kumar Jan 25 '22 at 15:39
  • Yes, that's what it means. – Barmar Jan 25 '22 at 15:45
  • @SaiKumar the term "pass by reference" is not really appropriate here; **all** function parameters in JavaScript are passed by value. It's just that "value", for objects and arrays etc, are references. It's confusing but the terminology is simply that way and there's nothing we can do about it. When you pass an array (or any other kind of object), you're passing a reference to the array. – Pointy Jan 25 '22 at 15:46
  • Does this answer your question? [Changing array in JavaScript function changes array outside of function?](https://stackoverflow.com/questions/10990647/changing-array-in-javascript-function-changes-array-outside-of-function) – Heretic Monkey Jan 25 '22 at 15:54

1 Answers1

1

... since I am passing a globalArray into the function, will a copy of the localArray be always stored as a new array in each callstack?

No. As the commenters on your question pointed out, arrays are passed as values by reference, meaning the globalArray variable represents the place in memory where that array exists. If you change a variable pointing to an array (i.e. globalArray = ...), you're only changing that variable. But if you modify an array (e.g. globalArray.push(...)), you're changing its contents for every variable that's looking to that array in memory, regardless of which variable name you use, or where it exists on the stack.

If I were to achieve the localArray as an incremental copy of the same localArray variable for each execution context, how would I be achieving that?

There are a few ways to do something like that.

For example, you could clone the array before passing it to the next level of recursion, but if you ended up recursing very deeply that could use a lot of time and memory creating arrays and copying values that you might never use.

Alternatively, rather than using arrays, you could create a memory structure similar to a linked list node, and each level adds a node to the end of the previous one to pass as a variable. That way it's still possible to traverse all the elements from the call stack when you need to, but you use an amount of memory that's proportionate to the depth of the call stack.

You could also reuse a single global array, which you push onto as the call stack gets deeper, but you pop off the values before you return from each level of recursion: basically maintaining a stateful stack parallel to the call stack.

The best approach will likely depend on the details of your recursive algorithm, and how much data you actually need to maintain at each level. In my experience, the local parameters passed in to each level are usually relatively "flat" summary values, such as the current depth of recursion, whereas the global variables are the ones where you maintain state.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315