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

Saa*_*adH 1 javascript recursion static-members

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

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
}
Run Code Online (Sandbox Code Playgroud)

这个函数的问题是,它对单个对象(树)完全正常,但是当在参数中传递另一个对象时,它只是将叶节点附加到已经从前一个树获得的叶节点.

例如,

// 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) 
Run Code Online (Sandbox Code Playgroud)

现在这样做的原因typeof retrieve.names == 'undefined'只是第一次.每当这个函数被再次调用时,构件names的的retrieve功能(其也被认为是一个对象)已被设置/初始化.

有没有办法在给定函数调用的递归函数内设置变量(或对象的成员),然后再次设置/设置它以进行另一个函数调用.

Poi*_*nty 5

你可以使用内部函数:

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;
}
Run Code Online (Sandbox Code Playgroud)

外部函数将空数组初始化为局部变量.内部函数与原始函数基本上完成相同的工作,但它引用了本地数组.

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


Ber*_*rgi 5

另一种方法(@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;
}
Run Code Online (Sandbox Code Playgroud)