在递归循环中迭代和处理JSON对象会导致堆栈超出错误

Iterating and processing JSON Object in recursive loop causes Stack Exceeded Error

本文关键字:堆栈 错误 出错 对象 JSON 循环 递归 迭代 处理      更新时间:2023-09-26

我正在尝试使用JS构建一个HTML页面。需要进入HTML的细节以json对象的形式从服务器发送过来。现在json对象的结构基本上模仿了dom结构,我遍历对象并从中获取单个html元素数据并呈现html字符串。当我使用递归函数来遍历这个对象时,就会出现这个问题。触发堆栈超出错误。我猜这是因为浏览器栈大小的限制。我想了解,我可以迭代这个对象来创建页面而不会导致脚本失败的最佳方式是什么。

pageObj Structure ->
//only a representation of object, the size is much larger.
{ "Default" : { "#text" : [ "'n  ",
          "'n"
        ],
      "MainForm" : { "#text" : [ "'n    ",
              "'n    ",
              "'n  "
            ],
          "shippingInfo" : { "#text" : [ "'n      ",
                  "'n      ",
                  "'n      ",
                  "'n      ",
                  "'n      ",
                  "'n      ",
                  "'n      ",
                  "'n    "
                ],
              "@attributes" : { "title" : "Shipping Information",
                  "type" : "FormBlock"
                },
              "Row" : [ { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "fName" : { "@attributes" : { "placeHolder" : "Enter First Name",
                            "title" : "First Name",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "lName" : { "@attributes" : { "placeHolder" : "Enter Last Name",
                            "title" : "Last Name",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "addr1" : { "@attributes" : { "title" : "Address 1",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "addr2" : { "@attributes" : { "title" : "Address 2",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n        ",
                        "'n      "
                      ],
                    "state" : { "@attributes" : { "title" : "State",
                            "type" : "text"
                          } },
                    "zipCode" : { "@attributes" : { "title" : "Zip Code",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n        ",
                        "'n      "
                      ],
                    "country" : { "@attributes" : { "title" : "Country",
                            "type" : "text"
                          } },
                    "phone" : { "@attributes" : { "title" : "Phone",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n        ",
                        "'n        ",
                        "'n        ",
                        "'n      "
                      ],
                    "day10" : { "@attributes" : { "title" : "10 day Shipping ($3)",
                            "type" : "radio"
                          } },
                    "day5" : { "@attributes" : { "title" : "5 Shipping ($10)",
                            "type" : "radio"
                          } },
                    "free" : { "@attributes" : { "title" : "Free Shipping ($0)",
                            "type" : "radio"
                          } },
                    "overNight" : { "@attributes" : { "title" : "One day Shipping ($20)",
                            "type" : "radio"
                          } }
                  }
                ]
            },
          "userInfo" : { "#text" : [ "'n      ",
                  "'n      ",
                  "'n      ",
                  "'n    "
                ],
              "@attributes" : { "title" : "User Information",
                  "type" : "FormBlock"
                },
              "Row" : [ { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "TextBox" : { "@attributes" : { "placeHolder" : "Select an username",
                            "title" : "Username",
                            "type" : "text"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "TextBox" : { "@attributes" : { "placeHolder" : "Select a password",
                            "title" : "Password",
                            "type" : "password"
                          } }
                  },
                  { "#text" : [ "'n        ",
                        "'n      "
                      ],
                    "TextBox" : { "@attributes" : { "placeHolder" : "Eg: name@gmail.com",
                            "title" : "Email",
                            "type" : "text"
                          } }
                  }
                ]
            }
        }
    } }

为了迭代这个对象,我使用了下面的技术:

function iterateJsonObj(obj) {
    for(key in obj) {
        if(!obj.hasOwnProperty(key) || key=="#text") {
            continue;
        }
        else if(obj[key]["@attributes"]!=null)
        {
            htmlStr += createHTMLStr(obj[key], key);
        }
        iterateJsonObj(obj[key]);
    }
}

希望这个问题有意义。

这是一个退化的复制情况:

iterateJsonObj("Some text");

你能看到发生了什么吗?显然,for循环处理字符串的方式类似于处理单字符子字符串的数组。"Shipping"[0]是"S",它本身就是一个字符串…

为了解决这个问题,我建议在以这种方式迭代它之前测试typeof obj[key] === "object"。

同样,编写单元测试。他们会让你的生活更轻松。:)