我无法理解为什么我用 JavaScript 编写的递归函数出现问题。当我向它提供一个大的 json 文件时,它陷入了无限循环。我有一种感觉,这与 JavaScript 闭包的工作方式有关。希望聪明的人可以查看我的代码并解释发生了什么。
我已将 line for line 函数移植到 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 Node 输出(不正确):
2/4/67/90/90/67/90/90
2/4/67/90/90/67/90/908
最佳答案
除了您在循环中使用的迭代器之外,您的 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);
}
}
}
关于JavaScript 递归奇怪的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38211767/