我想要实现的是创建一个函数,帮助我快速检查深层嵌套的javascript对象,api或库中给定属性的存在,并将结果作为相关路径返回,例如: root/child/child/match
。
这是我到目前为止所得到的:
function findNode(obj, str) {
var results = [], regx = new RegExp(str, "gi");
function innerFind(obj, str, currentPath) {
var i, propName, prop, result;
if (toString.call(obj) === "[object Array]") {
for (i = 0; i < obj.length; i++) {
if (typeof obj[i] === "object") {
innerFind(obj[i], str, currentPath + "[" + i + "]/");
}
}
} else {
for (propName in obj) {
if (regx.test(propName)) {
results.push(currentPath + propName + "/");
}
prop = obj[propName];
if (typeof prop === "object") {
innerFind(prop, str, currentPath + propName + "/");
}
}
}
}
if (typeof obj === "object") {
innerFind(obj, str, "root/");
}
return results;
}
它适用于中小型对象,但在较大的对象上失败并出现错误:RangeError: Maximum call stack size exceeded
。我理解错误被抛出,因为函数innerFind
从内部被多次调用。
所以我的问题是,如何使上述功能工作而不会出现RangeError
错误?并且有更好的更有效的方法吗?
答案 0 :(得分:1)
您想要解决的“大”对象中有循环引用。如果你不知道循环引用是什么,这是一个例子:
var obj = {
child: null
}
obj.child = obj;
您将无法使用该对象运行您的函数,因为它具有对自身的引用,使您可以永久地运行脚本并最终超过堆栈大小。
很难“修复”你的功能,因为找到这些引用很容易。那些循环引用本身可能非常复杂。