5

Let's say that I want to get a list of all the variables in the window that are user-defined. In other words, they're not properties or objects that the browser has created or defined in ECMAScript.

For example, let's say there's this script on a page:

<script>
    window.__$DEBUG = true;
    var Analytics = function() {};
</script>

I would like to be able to loop through window and get a list containing __$DEBUG and its value, and Analytics and its value:

var nonNatives = (function nonNative(scope) {
    var result = {};
    for (var child in scope) {
        if (!isNative(child)) {
            result[child] = scope[child];
        }
    }
    return result;
})(window);

Can this be done?

core
  • 32,451
  • 45
  • 138
  • 193

1 Answers1

6

I've previously done this by creating a single function (loaded before any other JS) which remembers the current keys of window (i.e. the built-in properties) and which when called again displays the differences.

If the purpose is just to detect accidentally global variables, the aforementioned function can be an anonymous IIFE (such that it doesn't itself pollute the global scope) which contains the current list in scope, which then periodically calls another enclosed function (with setTimeout) to compare the list, and update it for next time, e.g:

(function(scope) {

    var keys = Object.keys(scope);
    var map = {};
    for (var i = 0, n = keys.length; i < n; ++i) {
        map[keys[i]] = 1;
    }

    (function update() {
        var current = Object.keys(scope);

        // compare lists and print the differences
        for (i = 0, n = current.length; i < n; ++i) {
            var name = current[i];
            if (!(name in map)) {
                console.log(name + ' = ' + scope[name]);
                map[name] = 1;
            }
        }

        // loop
        setTimeout(update, 1000);
    })();

})(window);
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Can this be made into the form of a userscript? That is, can it be done by someone that cannot alter the server response in any way? – John Dvorak May 24 '13 at 15:48
  • @JanDvorak it's feasible I guess, but only if you can ensure that the userscript is always loaded first, and if the userscript can actually access the main page's `window` object. ISTR there are restrictions on userscripts that might prevent that, though. – Alnitak May 24 '13 at 15:50
  • Tampermonkey lets you configure whether to run the script on document-start / document-body / document-end and also the ordering of different userscripts. So, it _is_ feasible. IIRC, Greasemonkey lets you do the same. – John Dvorak May 24 '13 at 15:54
  • I've wrote a userscript that remembers the `keys(window)` on document start, and then compares them to the current set on request. Would there be any interest in this script? It trips the Google website, however, into thinking I'm a bot. – John Dvorak May 26 '13 at 17:48
  • curious - I wonder what they're detecting? Maybe it's the ever increasing `setTimeout` handler values? – Alnitak May 27 '13 at 13:36
  • Mine doesn't use `setTimeout`. Mine just reads the `window` and then it sits there until the dev accesses the object it places into `window`. Perhaps it doesn't like a property named `__vartrace__` being set on the `window`? – John Dvorak May 27 '13 at 13:41