微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaScript 遍历所有现有对象以查找对象键

如何解决JavaScript 遍历所有现有对象以查找对象键

我正在尝试调试由其他人构建的系统。我有一个缩小的库,它对外部数据源进行 ajax (xhr) 调用并将接收到的数据写入对象或变量。该调用是在页面加载后立即进行的,因此我无法通过附加一个函数注册所有 XHR 调用请求来捕获它。所以我试图通过浏览器窗口具有的所有变量和对象运行循环。我正在尝试这个:

var foundVar = false;
loopThroughObject(this);

function loopThroughObject(obj) {
  if (!foundVar) {
    try {
      for (var name in obj) {
        if (obj[name] && {}.toString.call(obj[name]) === '[object Function]') { //making sure that the object is not a function 
        } else {
          if (name == 'searchedKey') { //found the object with key = searchedKey
            console.log(obj[name]);
            foundVar = true;
          } else {
            setTimeout(loopThroughObject.bind(null,obj[name]),10); //do more recursion of inner objects
          }
        }
      }
    } catch (error) {}
  }
}

问题是 setTimeout(loopThroughObject.bind(null,0); 部分堆积起来并出现内存问题。我尝试了简单的 loopThroughObject(obj[name]),但在 25000 次循环后我面临“递归过多”错误。我似乎也遗漏了一些东西,它导致循环通过一些我不需要的对象类型。有谁知道一个更有效的方法来做这个循环?

附言我尝试了一个非常简单的 HTML 页面代码运行良好:

<html>
<head>
<script>
    var test = JSON.parse("{\"searchedKey\":\"12\"}");
    </script>
</head>
<body>
</body>
</html>

解决方法

问题几乎可以肯定是 window 有几个指向自身的属性,因此您的代码将进入无限循环。很可能还有其他循环引用。

您可以使用 Set 记住您已经查看过的对象,像这样(我还添加了一些其他调整;例如,您可以使用 typeof x === "function" 检查函数):

let foundVar = false;
let seen = new Set();
loopThroughObject(this);

function loopThroughObject(obj) {
    if (!foundVar) {
        try {
            for (const name in obj) {
                const value = obj[name];
                if (typeof value !== "function") {
                    if (name == "searchedKey") { // found the object with key = searchedKey
                        console.log(value);
                        foundVar = true;
                        break;
                    } else if (value && typeof value === "object" && !seen.has(value)) {
                        seen.add(value);
                        loopThroughObject(value); // No need for setTimeout
                    }
                }
            }
        } catch (error) {}
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。