72

列出站点已使用的所有全局变量的方法是什么?任何浏览器 javascript 调试器都可以做到这一点吗?使用我的意思是阅读,而不是更改/添加。检测 iframe 的,也会很好。

请注意:我需要获取站点“触及”的全局变量列表。不是所有的,也不是添加的或编辑的,那些在站点脚本中的任何地方都使用过的。

4

9 回答 9

89

在 Chrome 中,转到开发工具并打开控制台。然后输入以下内容:

Object.keys( window );

这将为您提供所有全局变量的数组。

编辑

在谷歌上搜索了一下,我找到了一种方法。您将需要firefoxjslinter插件。

设置完成后,打开 jslinter 并转到Options-> 检查左侧列中的所有内容,除了 "容忍未使用的参数"

然后在网页上运行 jslinter 并在结果中向下滚动。您将有一个未使用变量的列表(全局变量,然后是每个函数的局部变量)。

现在Object.keys(window);在控制台中运行并比较两者的结果以确定使用了哪些结果。

于 2013-06-24T13:06:20.630 回答
24

这个单行代码将使您非常接近,并且不需要在页面加载之前安装任何其他内容或运行代码:

Object.keys(window).filter(x => typeof(window[x]) !== 'function' &&
  Object.entries(
    Object.getOwnPropertyDescriptor(window, x)).filter(e =>
      ['value', 'writable', 'enumerable', 'configurable'].includes(e[0]) && e[1]
    ).length === 4)

它基于三个原则过滤 Object.keys(window):

  1. 为空或未定义的事物通常看起来并不有趣。
  2. 大多数脚本将定义一堆事件处理程序(即函数),但它们通常也没有兴趣转储。
  3. 由浏览器本身设置的窗口属性通常以特殊方式定义,它们的属性描述符反映了这一点。使用赋值运算符(即window.foo = 'bar')定义的全局变量具有特定外观的属性描述符,我们可以利用它。请注意,如果脚本使用具有不同描述符的 Object.defineProperty 定义属性,我们会错过它们,但这在实践中非常罕见。
于 2018-10-07T22:17:16.217 回答
17

我所做的是。我找到了一个尽可能少的 JavaScript / 框架的页面,将它们的所有键记录在数组中。然后迭代新页面上的所有键并仅记录上一个站点中未列出的键。你可以试试或使用我的代码片段

var ks = ["postMessage","blur","focus","close","frames","self","window","parent","opener","top","length","closed","location","document","origin","name","history","locationbar","menubar","personalbar","scrollbars","statusbar","toolbar","status","frameElement","navigator","customElements","external","screen","innerWidth","innerHeight","scrollX","pageXOffset","scrollY","pageYOffset","screenX","screenY","outerWidth","outerHeight","devicePixelRatio","clientInformation","screenLeft","screenTop","defaultStatus","defaultstatus","styleMedia","onanimationend","onanimationiteration","onanimationstart","onsearch","ontransitionend","onwebkitanimationend","onwebkitanimationiteration","onwebkitanimationstart","onwebkittransitionend","isSecureContext","onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmouseenter","onmouseleave","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onresize","onscroll","onseeked","onseeking","onselect","onstalled","onsubmit","onsuspend","ontimeupdate","ontoggle","onvolumechange","onwaiting","onwheel","onauxclick","ongotpointercapture","onlostpointercapture","onpointerdown","onpointermove","onpointerup","onpointercancel","onpointerover","onpointerout","onpointerenter","onpointerleave","onafterprint","onbeforeprint","onbeforeunload","onhashchange","onlanguagechange","onmessage","onmessageerror","onoffline","ononline","onpagehide","onpageshow","onpopstate","onrejectionhandled","onstorage","onunhandledrejection","onunload","performance","stop","open","alert","confirm","prompt","print","requestAnimationFrame","cancelAnimationFrame","requestIdleCallback","cancelIdleCallback","captureEvents","releaseEvents","getComputedStyle","matchMedia","moveTo","moveBy","resizeTo","resizeBy","getSelection","find","webkitRequestAnimationFrame","webkitCancelAnimationFrame","fetch","btoa","atob","setTimeout","clearTimeout","setInterval","clearInterval","createImageBitmap","scroll","scrollTo","scrollBy","onappinstalled","onbeforeinstallprompt","crypto","ondevicemotion","ondeviceorientation","ondeviceorientationabsolute","indexedDB","webkitStorageInfo","sessionStorage","localStorage","chrome","visualViewport","speechSynthesis","webkitRequestFileSystem","webkitResolveLocalFileSystemURL","addEventListener", "removeEventListener", "openDatabase", "dispatchEvent"]
var newKs = []
for (key in window) {
    if(ks.indexOf(key) == -1 && key !== "ks" && key !=="newKs") {
        newKs.push(key);
    }
}
console.log(newKs);

于 2018-07-31T11:02:31.600 回答
7

您可以尝试为此使用 getter,为所有现有的全局变量创建它。在页面启动之前运行它:

Object.keys(window) // or
Object.getOwnPropertyNames(window).concat(
  Object.getOwnPropertyNames(Object.getPrototypeOf(window))
) // or whatever
.forEach(function(name) {
    var d = Object.getOwnPropertyDescriptor(window, name),
        def = Object.defineProperty,
        log = console.log.bind(console);
    if (d && !d.configurable)
        return log("cannot detect accessing of "+name);
    def(window, name, {
        configurable: true,
        get: function() {
            log("window."+name+" was used by this page!");
            if (d) {
                def(window, name, d);
                return d.get ? d.get() : d.value;
            } else { // it was not an own property
                delete window[name];
                return window[name];
            }
        },
        set: function(x) {
            log("Ugh, they're overwriting window."+name+"! Something's gonna crash.");
        }
    });
});

当然,属性描述符等与旧浏览器不兼容。请注意,有些全局变量/window属性可能无法以编程方式列出(如on*处理程序),如果您需要它们,则必须在数组中显式列出它们。查看相关问题列出窗口对象的所有属性?跨浏览器有效的 JavaScript 名称

然而我猜想运行一个代码覆盖工具来抱怨未声明的全局变量,就像@stackErro 建议的那样,更有帮助。

于 2013-06-24T15:23:48.120 回答
7

由于这个问题是谷歌在搜索如何列出全局 javascript 变量的方法时的第一个问题,因此我将为此添加自己的答案。有时您需要列出全局变量以查看您的代码是否没有变量泄漏到范围之外(定义时不带 'var')。为此,请在调试控制台中使用它:

(function ()
{
   var keys=Object.keys( window );
   for (var i in keys)
   {
      if (typeof window[keys[i]] != 'function')
      console.log(keys[i], window[keys[i]]);
   }
})();

它将列出标准的全局变量,如窗口、文档、位置等。这些只是少数。所以你可以很容易地在列表中找到你泄露的变量。

于 2015-09-18T09:25:56.687 回答
3

将以下代码复制并粘贴到您的 javascript 控制台中

var keys = Object.getOwnPropertyNames( window ),
    value;

for( var i = 0; i < keys.length; ++i ) {
    value = window[ keys[ i ] ];
    console.log( value );
}

RightSaidFred 的所有功劳(Javascript - 转储所有全局变量

我希望这对你有帮助

于 2013-06-24T13:13:40.703 回答
2

列出我有时使用的全局变量的简单方法。在执行任何脚本之前,请尽可能早地放置此代码。

var WINDOW_PROPS = Object.keys(window);

然后,当您需要发现全局变量时,只需执行以下操作:

var GLOBALS = Object.keys(window)
    // filter the props which your code did not declare
    .filter(prop => WINDOW_PROPS.indexOf(prop) < 0)
    // prettify output a bit :) It's up to you...
    .map(prop => `${typeof window[prop]} ${prop} ${window[prop]}`)
    // sort by types and names to find easier what you need
    .sort();

console.log(GLOBALS.join("\n"));

我在这里使用了一些 ES6 特性来缩短代码。它仍然不适合生产,但足以用于调试目的,并且应该在现代浏览器中工作。

于 2017-08-17T09:59:35.677 回答
0

从 Object.keys(window) 中取出列表,删除浏览器默认生成的全局变量,只剩下你在页面上声明的全局变量。注意:您声明的函数也算作全局变量。

const listGlobal = ()=> { //for debugging purposes
    //put this function inside your html or javascript. Go to the html page.
    //In chrome console type listGlobal(); to see list of global vars

    //Array of global variables that exist in chrome browser by default
    var stdChromeVars = ["parent","opener","top","length","frames","closed","location","self","window","document","name","customElements","history","locationbar","menubar","personalbar","scrollbars","statusbar","toolbar","status","frameElement","navigator","origin","external","screen","innerWidth","innerHeight","scrollX","pageXOffset","scrollY","pageYOffset","visualViewport","screenX","screenY","outerWidth","outerHeight","devicePixelRatio","clientInformation","screenLeft","screenTop","defaultStatus","defaultstatus","styleMedia","onsearch","isSecureContext","onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","onformdata","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmouseenter","onmouseleave","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onresize","onscroll","onseeked","onseeking","onselect","onstalled","onsubmit","onsuspend","ontimeupdate","ontoggle","onvolumechange","onwaiting","onwebkitanimationend","onwebkitanimationiteration","onwebkitanimationstart","onwebkittransitionend","onwheel","onauxclick","ongotpointercapture","onlostpointercapture","onpointerdown","onpointermove","onpointerup","onpointercancel","onpointerover","onpointerout","onpointerenter","onpointerleave","onselectstart","onselectionchange","onanimationend","onanimationiteration","onanimationstart","ontransitionend","onafterprint","onbeforeprint","onbeforeunload","onhashchange","onlanguagechange","onmessage","onmessageerror","onoffline","ononline","onpagehide","onpageshow","onpopstate","onrejectionhandled","onstorage","onunhandledrejection","onunload","performance","stop","open","alert","confirm","prompt","print","queueMicrotask","requestAnimationFrame","cancelAnimationFrame","captureEvents","releaseEvents","requestIdleCallback","cancelIdleCallback","getComputedStyle","matchMedia","moveTo","moveBy","resizeTo","resizeBy","scroll","scrollTo","scrollBy","getSelection","find","webkitRequestAnimationFrame","webkitCancelAnimationFrame","fetch","btoa","atob","setTimeout","clearTimeout","setInterval","clearInterval","createImageBitmap","close","focus","blur","postMessage","onappinstalled","onbeforeinstallprompt","crypto","indexedDB","webkitStorageInfo","sessionStorage","localStorage","chrome","applicationCache","onpointerrawupdate","trustedTypes","speechSynthesis","webkitRequestFileSystem","webkitResolveLocalFileSystemURL","openDatabase","caches","ondevicemotion","ondeviceorientation","ondeviceorientationabsolute"];


    //load the current list of global variables
    let thisdocVars = Object.keys(window);

    //remove from the current list any variables that's in the browser default list
    stdChromeVars.forEach(DelFunc);
        function DelFunc(item) {
            thisdocVars.forEach((e,i)=>{if(e==item){thisdocVars.splice(i, 1);}});
        }

    //separate variables into functions and variables
    let thisdocfunc = [];
    let thisdocvar = [];
    thisdocVars.forEach((e)=>{if(typeof window[e]=="function"){thisdocfunc.push(e);}else{thisdocvar.push(e);}});
    console.log("Global Functions:\n" + thisdocfunc);
    console.log("Global Variables:\n" + thisdocvar);
    //Ctrl+Shift+i to see console in chrome
}
于 2020-07-31T12:34:19.853 回答
-1

您可以尝试使用 JetBrains PhpStorm,这就是我所做的,您可以免费试用 30 天,适用于任何系统。然后你检查 JSLint 或 JSHint 或两者我不记得然后你所有未使用的变量都带有下划线,用不同的颜色(根据主题)突出显示并且在滚动条上可见,当你将鼠标悬停在它们上面时,它表示未使用的变量;

编辑:我认为社区版现在是免费的。

于 2014-02-15T14:55:41.650 回答