简体   繁体   English

memory 如何在 JavaScript 中使用 arrays 进行递归分配

[英]How is memory allocation for recursion with arrays in JavaScript

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.我想了解,当我将 globalArray 作为参数发送给递归 function,并将相同的数组(localArray)分配给 globalArray 时,ZDE9B9ED78D7E2E911DCEEFFEE780ZF2 中的 memory 分配是如何发生的。 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?我知道每个递归都会有它自己的调用堆栈,并且它会有自己的变量副本,但是由于我将 globalArray 传递到 function 中,localArray 的副本是否总是存储为每个调用堆栈中的新数组?

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?如果我要实现 localArray 作为每个执行上下文的相同 localArray 变量的增量副本,我将如何实现呢?

Please view the image and code snippet请查看图片和代码片段在此处输入图像描述

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.但是,如果我稍微修改一下代码,将 localArray 设置为 null,如果它是一个被引用的值,那么 globalArray 仍然会保存数据。

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);

在此处输入图像描述

... 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? ...由于我将 globalArray 传递给 function,因此 localArray 的副本是否会始终作为新数组存储在每个调用堆栈中?

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.不。正如您问题的评论者指出的那样, arrays 作为值通过引用传递,这意味着globalArray变量表示 memory 中存在该数组的位置。 If you change a variable pointing to an array (ie globalArray =... ), you're only changing that variable.如果您更改指向数组的变量(即globalArray =... ),您只是在更改该变量。 But if you modify an array (eg 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.但是,如果您修改一个数组(例如globalArray.push(...) ),您将更改 memory 中查找该数组的每个变量的内容,无论您使用哪个变量名,或者它存在于堆栈中的什么位置.

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?如果我要实现 localArray 作为每个执行上下文的相同 localArray 变量的增量副本,我将如何实现呢?

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.例如,您可以在将数组传递到下一个递归级别之前克隆该数组,但如果您最终递归非常深入,这可能会花费大量时间,并且 memory 创建 arrays 并复制您可能永远不会使用的值。

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.或者,您可以创建类似于链表节点的 memory 结构,而不是使用 arrays 结构,并且每个级别在前一个节点的末尾添加一个节点以作为变量传递。 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.这样,仍然可以在需要时遍历调用堆栈中的所有元素,但是您使用的 memory 数量与调用堆栈的深度成正比。

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.您还可以重用单个全局数组,随着调用堆栈的深入,您可以将其push ,但是在从每个递归级别返回之前pop值:基本上维护一个与调用堆栈平行的有状态堆栈。

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.根据我的经验,传入每个级别的局部参数通常是相对“平坦”的汇总值,例如当前的递归depth ,而全局变量是您维护 state 的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM