JavaScript - 转储所有全局变量

39

在Javascript中,是否有一种方法可以获取页面上由Javascript/jQuery脚本声明的所有全局变量的列表或转储其内容?我特别关注数组。如果我能够获取数组名称,那就足够了。查看其值是额外的奖励。

8个回答

48
Object.keys( window );

这将为您提供window对象的所有可枚举属性(全局变量)的数组。
对于旧版浏览器,请包括来自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 );
}

7
您可以使用Object.getOwnPropertyNames(window)获取非可枚举属性。 - Raynos
1
在Chrome浏览器中,一些window的属性继承自Window.prototypeWindow。它们可以作为全局变量访问,但您需要将windowWindowWindow.prototype上的Object.getOwnPropertyNames结果连接在一起。 - Matthew
请参考此答案:https://dev59.com/VWQm5IYBdhLWcg3w6Car#17246535。将它们结合起来对我非常有效。 - Sourav Ghosh
它不起作用。ReferenceError: window未定义 - user5359531

5
以下函数仅转储已添加到window对象的全局变量:

(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是异步运行的。该代码使用全局变量,因为这使代码更易于理解。
你可以在这里这里看到它的工作原理,但请注意,这些示例显示了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检查已经足够。


所有的全局变量都是 window 对象的属性;ReferenceError: window is not defined - user5359531

2
你可以使用名为get-globals的npm包。它将window的属性与新创建的iframe进行比较,仅打印由开发者声明的变量,而不是浏览器厂商。

1

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'已被弃用。请改用'navigator.webkitTemporaryStorage'或'navigator.webkitPersistentStorage'。 - Jelmer

1

要获取“全局变量”对象,你可以使用这个函数:

function globals() { return this; }

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

2
顺便说一下,它不符合严格模式。 - Ry-
1
嗯...因为这是真的吗?在支持ES5的浏览器上查看:http://jsfiddle.net/G95gQ/ - Ry-
2
在严格模式下,当没有上下文时,thisnull。它不是全局对象。 - HoLyVieR
3
最后,若要挑剔的话,应该是 undefined 而不是 null :) - Ry-
这不就相当于全局使用 this 吗?在 Firefox 和 Node 控制台中,this === globals() 的结果都为 true,因为全局的 this 就是全局对象 - ChrisCrossCrash

0
这是一个简单的、更现代的代码片段,它记录了一个对象及其值的全局变量(而不仅仅是全局变量名),这通常是我在调试时寻找的内容。
(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的解决方案


0

获取泄露全局变量的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()以获取变量对象


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接