2015-06-19 74 views
0

我想寫一個遞歸函數,它基於索引數組返回我的模型中正確的嵌套對象。js遞歸函數不返回正確的子對象

我的控制檯日誌標記爲'內部函數'實際上顯示正確的obj!這讓我感到莫名其妙,因爲我之後所做的只是返回obj,但函數似乎再次運行並返回父項。

JSFiddle

var model = [ 
    { name: 'Item 1' }, 
    { 
     name: 'Item 2', 
     sub: [ 
       { name: 'Item 2.1' }, 
       { name: 'Item 2.2' }, 
       { name: 'Item 2.3' } 
     ] 
    }, 
    { name: 'Item 3' }, 
    { name: 'Item 4' } 
]; 

function getObj(collection, array) { 
    var data = collection[array[0]]; 
    if(array.length > 1) { 
     array.shift(); 
     arguments.callee(data.sub, array); 
    }  
    console.log('inside function', data); 
    return data; 
} 

var obj = getObj(model, [1, 2]); // expecting obj.name === 'Item 2.3' 
console.log('result', obj); // obj.name === 'Item 2' 
+0

[注意](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/參數/被調用者)_「ECMAScript(ES5)的第5版禁止在嚴格模式下使用arguments.callee()。​​」_ - 爲什麼不直接使用'getObj(...)'來獲得更好的支持? –

+0

謝謝,不知道..會更新。 – daviestar

回答

1

當你遞歸

arguments.callee(data.sub, array); 

你沒有返回結果,而不是你忽略結果並從最初的通話中返回數據。

嘗試在該行中添加return,以便遞歸調用的結果是整體函數的結果。

另請注意,arguments.callee將無法​​在嚴格模式下工作。

警告:第5版ECMAScript(ES5)禁止在嚴格模式下使用arguments.callee()。避免使用arguments.callee()或者給函數表達式一個名字,或者在函數必須調用它自己的地方使用函數聲明。

要嚴格模式下工作,你可以做

return getObj(data.sub, array); 
+0

謝謝,我認爲'arguments.callee'似乎是最佳實踐,因爲如果您決定更改函數名稱,則不需要更改多行,但很容易知道。 – daviestar

+1

@daviestar體面的IDE將允許您一次性重構名稱的所有實例,而不是手動手動更新它們。 –

+0

@JamesThorpe我使用PHPStorm ..我該怎麼做? – daviestar

0

你應該在遞歸返回以及:

function getObj(collection, array) { 

    var data = collection[array[0]]; 

    if(array.length > 1) { 
     array.shift(); 
     return arguments.callee(data.sub, array); 
    }  

    console.log('inside function', data); 

    return data; 
}