2016-07-05 96 views
2

我很难理解为什么我在JavaScript中编写的递归函数有问题。当我给它一个大的json文件时,它会陷入无限循环。我有一种感觉,它与JavaScript关闭如何工作有关。跳一些聪明的人可以看看我的代码并解释发生了什么。JavaScript递归古怪行为?

我已经将行的函数行移植到PHP,它产生了我期望的输出。

的JavaScript:

var jsonfile = process.argv[2]; 

json = require("./"+jsonfile); 

path = "2"; 

buildPaths(json, path); 

function buildPaths(json, path) { 

    if (json.Children == null || json.Children.length == 0) { 

     console.log(path + "/" + json.TypedItemId); 

    } else { 

     for (i = 0; i < json.Children.length; i++) { 
      buildPaths(json.Children[i], path + "/" + json.TypedItemId); 
     } 
    } 

} 

移植到PHP:用于测试

<?php 
$jsonfile = $argv[1]; 
$json = json_decode(file_get_contents($jsonfile)); 

$path = "2"; 

buildPaths($json, $path); 

function buildPaths($json, $path) { 


    if ($json->Children == null || count($json->Children) == 0) { 

     echo $path . "/" . $json->TypedItemId . "\n"; 

    } else { 

     for ($i = 0; $i < count($json->Children); $i++) { 
      buildPaths($json->Children[$i], $path . "/" . $json->TypedItemId); 
     } 
    } 

} 

样品JSON文件(文件较大造成更大的怪事):

{ 
    "TypedItemId": 4, 
    "Children": [ 
    { 
     "TypedItemId": 67, 
     "Children": [ 
     { 
      "TypedItemId": 90, 
      "Children": [ 
      { 
       "TypedItemId": 90, 
       "Children": [ 
       { 
        "TypedItemId": 67, 
        "Children": [ 
        { 
         "TypedItemId": 90, 
         "Children": [ 
         { 
          "TypedItemId": 90, 
          "Children": [] 
         }, 
         { 
          "TypedItemId": 908, 
          "Children": [] 
         } 
         ] 
        }, 
        { 
         "TypedItemId": 908, 
         "Children": [ 
         { 
          "TypedItemId": 90, 
          "Children": [] 
         }, 
         { 
          "TypedItemId": 908, 
          "Children": [] 
         } 
         ] 
        } 
        ] 
       } 
       ] 
      }, 
      { 
       "TypedItemId": 908, 
       "Children": [] 
      } 
      ] 
     }, 
     { 
      "TypedItemId": 908, 
      "Children": [ 
      { 
       "TypedItemId": 90, 
       "Children": [] 
      }, 
      { 
       "TypedItemId": 908, 
       "Children": [] 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

PHP输出(正确):

2/4/67/90/90/67/90/90 
2/4/67/90/90/67/90/908 
2/4/67/90/90/67/908/90 
2/4/67/90/90/67/908/908 
2/4/67/90/908 
2/4/67/908/90 
2/4/67/908/908 

JavaScript的节点输出(不正确):

2/4/67/90/90/67/90/90 
2/4/67/90/90/67/90/908 
+0

你没有在你的JS代码的任何封锁。只是一个正常的功能。 –

+0

好吧 仍然对引起不同产出的事情感到好奇。我想知道是什么关于JavaScript,我不明白,导致我看到 –

回答

4

没有错,你的JavaScript,除了迭代器使用的是在你的循环:

for (i = 0; i < json.Children.length; i++) { 

相反的声明使用var一个局部变量您在全局对象上使用属性i作为迭代器,它将在所有调用buildPaths之间共享。

使用本地变量,而不是:

for (var i = 0; i < json.Children.length; i++) { 

自己尝试一下:

var json = {"TypedItemId":4,"Children":[{"TypedItemId":67,"Children":[{"TypedItemId":90,"Children":[{"TypedItemId":90,"Children":[{"TypedItemId":67,"Children":[{"TypedItemId":90,"Children":[{"TypedItemId":90,"Children":[]},{"TypedItemId":908,"Children":[]}]},{"TypedItemId":908,"Children":[{"TypedItemId":90,"Children":[]},{"TypedItemId":908,"Children":[]}]}]}]},{"TypedItemId":908,"Children":[]}]},{"TypedItemId":908,"Children":[{"TypedItemId":90,"Children":[]},{"TypedItemId":908,"Children":[]}]}]}]}; 
 

 
var path = "2"; 
 

 
buildPaths(json, path); 
 

 
function buildPaths(json, path) { 
 
    if (json.Children == null || json.Children.length == 0) { 
 
     console.log(path + "/" + json.TypedItemId); 
 
    } else { 
 
     for (var i = 0; i < json.Children.length; i++) { 
 
      buildPaths(json.Children[i], path + "/" + json.TypedItemId); 
 
     } 
 
    } 
 
}

+0

辉煌的结果!我是一个全球变量LOL。现在测试它。 Ty =) –

+1

为了方便捕捉这些类型的错误,请确保使用'strict strict'启用严格模式。 –

+0

是的!感谢您成为我的代码审查的目光。 –