При условии, что JSON передается вашей функции в том виде, в каком вы ее опубликовали , я пришел к следующему решению (я изменил некоторые из номенклатуры, а также заменил два экземпляра, создав объект и присвоив ему массив к нему для вложенных объектов):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en">
<head>
<title>JSON Test Case</title>
<script type="application/javascript">
/* <![CDATA[ */
'use strict';
var nested = 0;
function loadNodes(p_obj, p_current_group_node)
{
let l_i;
let l_new_group_node;
nested++;
console.log('Entering loadNodes (' + nested + ')...');
console.log('Length of object: ' + p_obj.length); // Oops...!
console.log('Type of JSON object: ' + typeof p_obj);
console.log('Determining the node type: ' + p_obj.nodetype);
console.log('Node name: ' + p_obj.name);
if(p_obj.nodetype == 'group')
{
console.log('Number of elements: ' + p_obj.children.length);
for(l_i = 0; l_i < p_obj.children.length; l_i++)
{
console.log('Found a subtree for processing!');
l_new_group_node = new Object();
l_new_group_node.nodes = new Array();
p_current_group_node.nodes.push(l_new_group_node);
loadNodes(p_obj.children[l_i], l_new_group_node);
}
}
else
console.log('Process leaf node here...');
console.log('Leaving loadNodes (' + nested + ')...');
nested--;
}
/* ]]> */
</script>
</head>
<body>
<header><h1>JSON test case</h1></header>
<main>
<script type="application/javascript">
/* <![CDATA[ */
var json = {
"nodetype": "group",
"name": "root",
"matrix": [
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
],
"children": [
{
"nodetype": "group",
"name": "driver-cube-group",
"matrix": [
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
],
"children": [
{
"nodetype": "aabox",
"name": "driver-cube",
"minpoint": {
"x": -3,
"y": -3,
"z": -3,
"w": 1
},
"maxpoint": {
"x": -2,
"y": -2,
"z": -2,
"w": 1
},
"color": {
"x": 1,
"y": 1,
"z": 1,
"w": 1
}
}
]
}
]
}
var myobj = new Object();
myobj.nodes = new Array();
loadNodes(json, myobj);
/* ]]> */
</script>
</main>
</body>
</html>
Прежде всего, я мог бы выбросить внешний цикл, потому что он даже не запускается и поэтому предотвращает рекурсию (я обнаружил, что p_obj.length
даже возвращает undefined
, если вы пытаетесь получить доступ к этому свойству) , В конце концов, это объект, и это, очевидно, не обеспечивает длину. Вместо этого я проверяю параметры объекта, который мы получили, и затем определяю, нужно ли нам спускаться дальше или мы достигли конечного узла.
Если нам нужно спуститься дальше, то в действительности существует цикл, который копает массив, присвоенный свойству children
- который на самом деле имеет длину, поэтому мы можем принять его для нашего условия завершения.
Если вы хотите увидеть, что на самом деле происходит, вы можете запустить этот тестовый пример с открытой консолью вашего браузера. Я вставил различные заявления, в которых записана конкретная информация, чтобы вы могли видеть, что здесь делается.
Также следует обратить внимание на записи Ввод loadNodes (...) и Выход из loadNodes (...) , потому что они сообщают вам, где на самом деле происходит рекурсия и когда рекурсивно Вызванная функция оставлена. Вы можете найти уровень вложенности в скобках.