如何搜索浏览器窗口对象以查找哪个对象或变量具有搜索到的值?

问题描述 投票:0回答:1

如果我知道我有一个值“JohnSmith”存储在浏览器全局空间中的某个对象中,并且我遇到了某个断点,我如何知道哪个对象或变量的值为“JohnSmith”?我有数百个对象,我不想在开发工具中手动搜索它。 我在控制台或代码片段中使用了一些脚本来遍历所有对象,但它们都无法正确搜索或给出一些错误消息。

我尝试了JS Runtime Inspector,它看起来很有前途,但它在我的 Chrome 61 版本中根本不起作用。它的子选项卡不像他们的视频那样显示。

javascript google-chrome google-chrome-devtools
1个回答
12
投票

这是一个可配置的挖掘器,您可以将其保留在 devtools snippets panel 中并通过键盘运行:

  • CtrlP(或P),然后
    !name
    ,其中
    name
    是代码片段的名称
  • 编辑代码片段的代码时按
  • CtrlEnter(或 Enter)。
((
  haystack = window, // $0 is the last inspected DOM element
  needle = 'foo', // 'foo' or /foo\d+/ or /foo/iu
  target = 'kv', // kv = keys and values, k = keys only, v = values only
  caseSensitive = true, // for a plain string needle
  ownKeysOnly = !true, // only dig into own keys in objects
  maxResults = 1000, // 0 = don't limit
  skipValues = new Set([haystack, window, document.doctype]),
) => {
  let isRe, fnLow, fnIn, num = 0;
  const isSimpleId = /^[_$a-z][$\w]*$/iu;
  const path = [], pathKeys = [], inK = /k/i.test(target), inV = /v/i.test(target);
  if (!(isRe = needle instanceof RegExp)) {
    fnIn = dig.call.bind(''.includes);
    if (!caseSensitive) needle = (fnLow = dig.call.bind(''.toLowerCase))(needle);
  }
  dig(haystack);
  function check(v, name) {
    const t = typeof v;
    const n = typeof name === 'symbol' ? name.description : name;
    if (inK && (isRe ? needle.test(n) : fnIn(fnLow ? fnLow(n) : n, needle)) ||
        inV && (t === 'string' || t === 'number') &&
        (isRe ? needle.test(v) : fnIn(fnLow ? fnLow(v) : v, needle))) {
      let p = '';
      for (const k of pathKeys)
        p += !isSimpleId.test(k) ? `[${k}]` : p ? '.' + k : k;
      console.log('#%s %s: %o in %o', ++num, name, v,
        {obj: path.at(-1), path: p, ancestry: path.slice(0)});
      if (!--maxResults) return 1;
    }
    if (v && t === 'object' && !skipValues.has(v)) {
      skipValues.add(v);
      pathKeys.push(name);
      return dig(v);
    }
  }
  function dig(o) {
    path.push(o);
    let res;
    if (Array.isArray(o)) {
      for (let len = o.length, i = 0; i < len; i++)
        if (check(o[i], i)) { res = 1; break; }
    } else if (o instanceof Map || o instanceof Set) {
      for (const e of o.entries())
        if (check(e[1], e[0])) { res = 1; break; }
    } else if (typeof o === 'object') {
      for (const k in o)
        if ((!ownKeysOnly || Object.hasOwn(o, k)) &&
            !(o === window && k.startsWith('webkit')))
          try { if (check(o[k], k)) { res = 1; break; } } catch(e) {}
    }
    path.pop();
    pathKeys.pop();
  }
})();

© www.soinside.com 2019 - 2024. All rights reserved.