繁体   English   中英

Javascript:在递归函数中初始化一次变量(如静态变量)

[英]Javascript: initializing a variable once (like a static variable) in a recursive function

我有一个递归函数,它返回树的叶节点(以嵌套对象的形式):

var retrieve = function (a)
{
    if (typeof retrieve.names == 'undefined') //would be true for the 1st pass only
        retrieve.names = []
    if (a.left != null)
        retrieve (a.left)
    if (a.right != null)
        retrieve (a.right)
    if (a.left == null && a.right == null)
        retrieve.names.push(a)
    return retrieve.names
}

这个函数的问题是,它对单个对象(树)工作得很好,但是当另一个对象传入参数时,它只是简单地将叶子节点附加到已经从前一棵树获得的叶子节点上。

例如,

// gets the leaf nodes of obj1 tree
obj1_leaves = retrieve(obj1) 

// instead of only getting leaf nodes of obj2, it appends them to leaf nodes of obj1
obj2_leaves = retrieve(obj2) 

现在的原因是typeof retrieve.names == 'undefined'仅在第一次为真。 每当再次调用此函数时, retrieve函数的成员names (也可以视为对象)已经设置/初始化。

有没有办法只为给定的函数调用在递归函数中设置变量(或对象的成员),然后为另一个函数调用再次取消设置/设置它。

您可以使用内部函数:

function retrieve(a) {
  var names = [];
  function _retrieve(a) {
    if (a.left != null)
      _retrieve (a.left)
    if (a.right != null)
      _retrieve (a.right)
    if (a.left == null && a.right == null)
      names.push(a)
   }
   _retrieve(a);
   return names;
}

外部函数将空数组初始化为局部变量。 内部函数与原始函数基本相同,但是它引用该本地数组。

每次retrieve() ,都会创建一个新的本地数组,并将其用于遍历树。

另一种方法(对于@Pointy给出的方法,我不再重复)是使用可选参数。 它仅在“第一个”最外层调用中填充默认值,然后传递给每个递归调用。

function retrieve(a, names) {
    if (!names) names = [];

    if (a.left != null)
        retrieve(a.left, names);
    if (a.right != null)
        retrieve(a.right, names);
    if (a.left == null && a.right == null)
        names.push(a);
    return names;
}

只需在定义中使用等号执行默认值,仅在未提供参数时才初始化。 然后在随后的内部调用中继续传递相同的密钥:

function something(a, b=[]){
 // then just call 'something'  passing b when recursing
 // for example
   something(a-1, b)
}

由于对象的值是通过引用传递的,因此相同的对象将在递归调用之间共享

暂无
暂无

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

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