Javascript - dumping all global variables

后端 未结 8 1884
迷失自我
迷失自我 2020-11-28 05:39

Is there a way in Javascript to get a list or dump the contents of all global variables declared by Javascript/jQuery script on a page? I am particularly interested in array

相关标签:
8条回答
  • 2020-11-28 06:00

    window is the global object in a browser, and you can use a for..in loop to loop through its properties:

    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] + '!');
        }
    }
    
    0 讨论(0)
  • 2020-11-28 06:06
    Object.keys( window );
    

    This will give you an Array of all enumerable properties of the window object, (which are global variables).

    For older browsers, include the compatibility patch from MDN.


    To see its values, then clearly you'll just want a typical enumerator, like for-in.


    You should note that I mentioned that these methods will only give you enumerable properties. Typically those will be ones that are not built-in by the environment.

    It is possible to add non-enumerable properties in ES5 supported browsers. These will not be included in Object.keys, or when using a for-in statement.


    As noted by @Raynos, you can Object.getOwnPropertyNames( window ) for non-enumerables. I didn't know that. Thanks @Raynos!

    So to see the values that include enumerables, you'd want to do this:

    var keys = Object.getOwnPropertyNames( window ),
        value;
    
    for( var i = 0; i < keys.length; ++i ) {
        value = window[ keys[ i ] ];
        console.log( value );
    }
    
    0 讨论(0)
  • 2020-11-28 06:09

    You can use npm package called get-globals. It compares properties of window with fresh-created iframe to print only variables declared by dev(s), not browser vendor.

    0 讨论(0)
  • 2020-11-28 06:09

    Here’s a simple, more modern snippet that logs an object with the globals and their values (rather than just the global variable names), which is usually what I’m looking for when debugging:

    (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)
    })()
    

    Tip: You can also swap 'about:blank' with window.location to get only the globals set since the page was first loaded.

    This uses an iframe to determine which properties to ignore like robocat’s answer, but it’s based on David Walsh’s solution.

    0 讨论(0)
  • 2020-11-28 06:10

    Since all global variables are properties of the window object, you can get them using:

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

    Since all default/inherited properties are not plain arrays (mostly host objects or functions), the Array.isArray check is sufficient.

    0 讨论(0)
  • 2020-11-28 06:17

    The following function only dumps global variables that have been added to the window object:

    (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);
        };
    })();
    

    It works by using an iframe to get a clean list of global window variables, then comparing that with the list of global variables in the current window. It uses a button because the iframe runs asynchronously. The code uses a global variable because that makes the code easier to understand.

    You can see it working here or here, although note that these examples show many global variables "leaked" by jsbin itself (different depending on which link you use).

    0 讨论(0)
提交回复
热议问题