簡體   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