【问题标题】:Javascript - dumping all global variablesJavascript - 转储所有全局变量
【发布时间】:2026-02-14 16:40:01
【问题描述】:

在 Javascript 中是否有办法获取列表或转储页面上由 Javascript/jQuery 脚本声明的所有全局变量的内容?我对数组特别感兴趣。如果我能得到数组名称,那对我来说就足够了。看到它的价值是一种奖励。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:
    Object.keys( window );
    

    这将为您提供window 对象的所有可枚举属性的数组(它们是全局变量)。

    对于旧版浏览器,请包含 the compatibility patch from MDN


    要查看它的值,显然您只需要一个典型的枚举器,例如 for-in


    您应该注意,我提到这些方法只会为您提供可枚举属性。通常这些将不是环境内置的。

    可以在支持 ES5 的浏览器中添加 不可枚举 属性。这些不会包含在Object.keys 中,或者在使用for-in 语句时。


    正如@Raynos 所指出的,您可以Object.getOwnPropertyNames( window ) 用于非枚举。我不知道。谢谢@Raynos!

    所以要查看包含可枚举的值,您需要这样做:

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

    【讨论】:

    • 您也可以将Object.getOwnPropertyNames( window ) 用于不可枚举
    • 谢谢@Raynos。我不知道。添加到答案。
    • 在 Chrome 上,window 的一些属性继承自 Window.prototypeWindow。它们可以作为全局变量访问,但您需要将windowWindowWindow.prototype 上的 Object.getOwnPropertyNames 结果连接在一起
    • 也看到这个答案:*.com/a/17246535/4040525 将它们结合起来对我来说效果很好
    【解决方案2】:

    以下函数仅将已添加的全局变量转储到窗口对象:

    (function(){
        //noprotect <- this comment prevents jsbin interference
        var windowProps = function() {
            // debugger;
            var result = {};
            for (var key in window) {
                if (Object.prototype.hasOwnProperty.call(window, key)) {
                    if ((key|0) !== parseInt(key,10)) {
                        result[key] = 1;
                    }
                }
            }
            window.usedVars = result;
        };
    
        var iframe = document.createElement('iframe');
        iframe.style.display = 'none';
        iframe.src = 'about:blank'; 
        document.body.appendChild(iframe);
        var fwin = iframe.contentWindow;
        var fdoc = fwin.document;
        fdoc.open('text/html','replace');
        fdoc.write('<!DOCTYPE html><body><script>window.onload = ' + windowProps.toString() + '<\u002Fscript>');
        fdoc.close();
    
        var button = document.createElement('input');
        button.type = 'button';
        button.value = 'go';
        document.body.appendChild(button);
        button.onclick = function() {
            var clean = fwin.usedVars;
            windowProps();
            var dirty = window.usedVars;
            for (var key in clean) {
                delete dirty[key];
            }
            for (var variable in dirty) {
                var div = document.createElement('div');
                div.textContent = variable;
                document.body.appendChild(div);     
            }
            document.body.removeChild(button);
            document.body.removeChild(iframe);
        };
    })();
    

    它的工作原理是使用 iframe 获取全局窗口变量的干净列表,然后将其与当前窗口中的全局变量列表进行比较。它使用一个按钮,因为 iframe 异步运行。代码使用全局变量,因为这使代码更容易理解。

    您可以看到它在 herehere 工作,但请注意,这些示例显示许多全局变量被 jsbin 本身“泄露”(取决于您使用的链接)。

    【讨论】:

      【解决方案3】:

      由于所有全局变量都是window 对象的属性,您可以使用:

      for(var key in window) { // all properties
          if(Array.isArray(window[key])) { // only arrays
              console.log(key, window[key]); // log key + value
          }
      }
      

      由于所有默认/继承属性都不是普通数组(主要是宿主对象或函数),Array.isArray 检查就足够了。

      【讨论】:

        【解决方案4】:

        要获取“全局”对象,您可以使用此函数:

        function globals() { return this; }
        

        这是测试: http://jsfiddle.net/EERuf/

        【讨论】:

        • 顺便说一句,不符合严格模式:)
        • 嗯...因为这是真的?在兼容 ES5 的浏览器上看看这个:jsfiddle.net/G95gQ
        • @c-smile 在没有上下文的严格模式下,thisnull。它不是全局对象。
        • @HoLyVieR:最后,吹毛求疵,不是null,而是undefined :)
        • 这不是和全局使用this一样吗? this === globals() 在 Firefox 和 Node 控制台中的计算结果为 true,因为在全局范围内 this 只是 global object
        【解决方案5】:

        window 是浏览器中的全局对象,您可以使用for..in 循环来循环其属性:

        if(!Array.isArray) {
            Array.isArray = function(obj) {
                return Object.prototype.toString.call(obj) === '[object Array]';
            };
        }
        
        for(var x in window) {
            if(Array.isArray(window[x])) {
                console.log('Found array ' + x + ' in ' + window + ', it has the value ' + window[x] + '!');
            }
        }
        

        【讨论】:

        • 我知道这是一个相当老的答案,但是'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
        【解决方案6】:

        您可以使用名为 get-globals 的 npm 包。它将window 的属性与新创建的iframe 的属性进行比较,以仅打印由dev(s) 声明的变量,而不是浏览器供应商。

        【讨论】:

          【解决方案7】:

          Greasymonkey 脚本获取泄露的全局变量

          // ==UserScript==
          // @name        SCI
          // @namespace   ns
          // @version     1
          // @grant       none
          // @run-at      document-start
          // ==/UserScript==
          console.log('SCI loaded');
          var SCI = window.SCI = {
                  defprops: [],
                  collect: function(){
                      var wprops = [];
                      for(var prop in window){
                          wprops.push(prop);
                      }
                      return wprops;
                  },
                  collectDef: function(){
                      this.defprops = this.collect(); 
                  },
                  diff: function(){
                      var def = this.defprops,
                          cur = this.collect();
                      var dif = [];
                      for(var i = 0; i < cur.length; i++){
                          var p = cur[i];
                          if(def.indexOf(p) === -1){
                              dif.push(p);
                          }
                      }
                      return dif;
                  },
                  diffObj: function(){
                      var diff = this.diff();
                      var dobj = {};
                      for (var i = 0; i < diff.length; i++){
                          var p = diff[i];
                          dobj[p]=window[p];
                      }
                      return dobj;
          
                  }
          };
          SCI.collectDef();
          

          使用在控制台中运行SCI.diff() 获取名称列表或使用SCI.diffObj() 获取带有变量的对象

          【讨论】:

            【解决方案8】:

            这是一个简单、更现代的 sn-p,它使用全局变量它们的值(而不仅仅是全局变量名)记录一个对象,这通常是我在调试时要寻找的:

            (function () {
                const iframe = document.createElement('iframe')
                iframe.setAttribute('hidden', '')
                iframe.src = 'about:blank'
                iframe.onload = function () {
                    // Iterate through the properties of the current `window` and reduce the output
                    // to only properties that are not in the iframe’s `window`.
                    console.debug(Object.entries(window).reduce((reducedObj, [property, value]) => {
                        // Check if the property does not exist in the iframe and if so, add it to
                        // the output object.
                        if (! (property in iframe.contentWindow))
                            reducedObj[property] = value
                        return reducedObj
                    }, {})))
                    // Clean up the iframe by removing it from the DOM.
                    iframe.remove()
                }
                // Append the iframe to the DOM to kick off loading.
                document.body.append(iframe)
            })()
            

            提示:您还可以将 'about:blank'window.location 交换,以仅获取自页面首次加载以来设置的全局变量。

            这使用 iframe 来确定要忽略的属性,例如 robocat’s answer,但它基于 David Walsh’s solution

            【讨论】: