最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

recursion - Javascript: initializing a variable once (like a static variable) in a recursive function - Stack Overflow

programmeradmin0浏览0评论

I have a recursive function, which returns the leaf nodes of a tree (which is in the form of nested objects):

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
}

The problem with this function is, it works perfectly fine for a single object (tree), but when another object is passed in the parameter, it simply appends the leaf nodes to the leaf nodes already obtained from the previous tree.

For instance,

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

Now the reason for this is typeof retrieve.names == 'undefined' is true only for first time. Whenever this function is invoked again, the member names of the retrieve function (which can also be considered as an object) is already set/initialized.

Is there a way to set a variable (or member of an object) inside a recursive function for a given function call only, and then unset/set it again for another function call.

I have a recursive function, which returns the leaf nodes of a tree (which is in the form of nested objects):

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
}

The problem with this function is, it works perfectly fine for a single object (tree), but when another object is passed in the parameter, it simply appends the leaf nodes to the leaf nodes already obtained from the previous tree.

For instance,

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

Now the reason for this is typeof retrieve.names == 'undefined' is true only for first time. Whenever this function is invoked again, the member names of the retrieve function (which can also be considered as an object) is already set/initialized.

Is there a way to set a variable (or member of an object) inside a recursive function for a given function call only, and then unset/set it again for another function call.

Share Improve this question asked Oct 21, 2015 at 19:52 SaadSaad 1,3604 gold badges27 silver badges42 bronze badges 2
  • Yes. Just don't make it static. – Bergi Commented Oct 21, 2015 at 19:55
  • I sense you actually want to use two functions. – Bergi Commented Oct 21, 2015 at 19:55
Add a ment  | 

3 Answers 3

Reset to default 6

You can use an inner function:

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

The outer function initializes the empty array as a local variable. The inner function does essentially the same work as your original function, but it references that local array.

Every time retrieve() is called, a new local array is created and used to traverse the tree.

An alternative approach (to the one given by @Pointy, which I'm not going to repeat) is to use an optional parameter. It is filled with the default value only on the "first", outermost call, and then passed through to each recursive invocation.

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

just do default value with equals sign, in the definition, that's only initialized if no parameter is provided. Then in subsequent internal calls keep passing the same key:

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

Since values are passed by reference for objects, same object will be shared across recursive calls

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论