【问题标题】:Finding JavaScript function in the global scope在全局范围内查找 JavaScript 函数
【发布时间】:2012-09-08 10:11:40
【问题描述】:

有没有办法在当前活动的对象模型中搜索 JavaScript 属性(例如命名函数)(Firebug 在“DOM”选项卡上显示的内容,我在 Chrome 开发人员工具中找不到直接等效项)当前加载的页面,使用主要浏览器的通用开发工具?

例如,我搜索“beta”,开发人员工具显示类似window.alpha.beta 的内容,这意味着某个脚本文件在窗口对象上创建了一个名为“alpha”的对象,该对象具有属性 beta。

我明确想在所有脚本文件中搜索字符串(例如,Chrome 开发者工具中的Ctrl-Shift-F)。

用例是我想从扩展/用户脚本调用页面的功能。我知道该函数存在,但它是使用复杂的框架创建的,我不知道它在页面的对象模型中的哪个位置结束。

PS:欢迎对问题进行与术语相关的编辑。

【问题讨论】:

  • 如果没有人提供原生答案,请考虑以 window 开头的递归 for..in 搜索(并跳过 window.window / current === child)。
  • @MattWhipple 这正是我感兴趣的相反情况。我确实在 Chrome 开发工具的“资源”选项卡上看到了函数定义。问题是我不知道代码执行后它在页面的对象模型上的位置。
  • 如果您点击开发者工具中的元素选项卡,您可以点击任何元素,在右侧面板上,您可以点击属性,您可以打开第一个元素以查看与所选对象关联的所有对象/属性元素。为了探索 window 对象,您可以进入 Sources 选项卡并为“window”添加一个监视表达式,它也可以让您探索所有全局对象和函数。你检查过这个吗?
  • @AkashKava 是的,谢谢,这是正确的方向。不幸的是,有很多这样的功能(2 MiB 的缩小 JS)并且它们位于复杂的对象模型中,因此手动“浏览”树在最坏的情况下是没有希望的,在最好的情况下是时间密集的。这就是为什么我一直在寻找一种方法来搜索它(因为我确实知道属性的名称,只是不知道它在哪里)。

标签: javascript dom firebug google-chrome-devtools


【解决方案1】:

加载https://github.com/angus-c/waldo 并从控制台使用它看起来应该可以解决问题。稍微复杂一点,但也与工具无关。

【讨论】:

  • 谢谢,这看起来很棒,而且似乎完全符合我在其他所有页面上的要求。不幸的是,它在我需要它的页面上不起作用......现在正在调查。
  • 如果您发布了该功能,也许我们可以提供更多帮助。现在听起来您想要的功能无法通过对象模型获得。这可能是一个关闭。 @hheimbuerger
  • @Makaze 我不知道这个功能!这正是用例:我正在尝试找到它的定义!如果我知道这个函数是什么样子的,我就不会再有问题了。用例是我看到一个工作函数调用(比如说myfunc()),我想知道函数在对象模型中的位置(答案可能类似于window.someobj.myfunc,但这正是我想要的弄清楚)。假设代码库是一些模糊的框架,例如Twitter 或 Facebook 订阅源。
  • 我明白了。我认为,Waldo 解决方案不起作用有几个可能的原因。 1.) 有问题的函数是匿名的。我认为可能是这样,但如果我错了,请纠正我。每次运行时都可能重新定义它。 2.) 该函数不是对象模型的一部分(它是另一个函数中的普通变量闭包)。 3.) 没有从您正在检查的窗口调用该函数(也许它在 iframe 中?)。在这种情况下,也可以通过将 Waldo 的代码应用到 iframe 的全局范围来访问该函数。
【解决方案2】:

我把评论中提到的递归类型函数写成了匿名函数

(function(searchTerm, parent, parentStr, depthLeft, parentsArr){
    var p = parent || window,
        child, cObj = null,
        s = parentStr || '',
        r = [],
        d = (depthLeft > 0 ? depthLeft-1 : 5),
        pArr = parentsArr || [p];
    for( child in p ){
        cObj = p[child];
        if ( child === searchTerm ) r[ r.length ] = (s+'.'+child).slice(1);
        if( d > 0 && cObj !== null && p.hasOwnProperty(child) && typeof cObj === 'object' && cObj !== p && pArr.indexOf(cObj) === -1 )
            r = r.concat( arguments.callee( searchTerm, cObj, s+'.'+child, d, pArr.concat([cObj]) ) );
    }
    return r;
})('createElement');

最后一行表示将从window开始搜索.createElement。 越深入,需要的时间就越长。

【讨论】:

  • 您可能需要尝试/捕捉cObj = p[child]; 并在捕捉中执行cObj = null 以避免TypeErrors
【解决方案3】:

如果函数是全局的,您可以使用 this constructor 从用户脚本中调用它:

var global = new Global(); // Initialize the Global constructor
// Some code
var globalVar = global.get('variableName'); // Assign the global variable 'variableName' to the local variable 'globalVar'

由于无法从全局范围调用闭包,因此您必须使用字符串搜索来获取其中任何一个(据我所知)。

【讨论】:

    【解决方案4】:

    我能想到的唯一方法是解析你的脚本并使用正则表达式来避免字符串和其他你可能不想要的情况。

    【讨论】:

    • 这并没有告诉我函数在对象模型的哪个位置结束。同样,我面前确实有函数的源代码。我正在寻找它被加载到的 DOM 中的点。
    • 那么,你想得到什么样的回报呢?一段代码,一个 DOM 元素,还是什么?
    • 属性的对象模型“路径”,例如。请参阅问题中提到的示例,它将是window.alpha.beta。或者,在开发者工具 UI 的某个地方弹出并突出显示的对象也可以。
    • 我误解了你的问题。我以为你在找一段剧本,所以我才告诉你。
    • 因为我预计人们会误读我的问题,所以我明确表示我不是在寻找问题中的一段脚本。 ;)
    猜你喜欢
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 2011-06-07
    • 2015-03-22
    相关资源
    最近更新 更多