6

I want watch for the creation of new global variables in Javascript so that, anytime a global variable is created, an event is fired.

I've heard of the watch() function but that is only for watching for specific variable names. I want a catchall.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Sridatta Thatipamala
  • 2,182
  • 4
  • 17
  • 18

4 Answers4

6

If you already know which names pollute your global namespace (see Intercepting global variable definition in javascript), you can use this trick to figure out when does it actually happen:

window.__defineSetter__('someGlobalVar', function() {
    debugger;
});

Be sure to have your developer tools open when you run this. Obviously works only if your browser supports __defineSetter__ but that's true for modern browsers. Also, don't forget to remove your debug code after you've finished.

Found here.

Community
  • 1
  • 1
Dmitry Pashkevich
  • 13,431
  • 9
  • 55
  • 73
3

I don't know how to make this work "on demand" as soon as a var is created, but I can suggest a polling approach. In a browser window, all global become a member of the global "window" object. (Because technically, "window" is the "global object"). So you could do something like the following:

1) enumerate all the properties on a window

window.proplist = window.proplist || {};
for (propname in window) {

    if (propname !== "proplist") {
      window.proplist[propname] = true;
    }
}

2) Set a timer to periodically "poll" window for new properties

setInterval(onTimer, 1000);

3) Wake up on the timer callback and look for new props

function onTimer() {
        if (!window.proplist) {
            return;
        }

        for (propname in window) {

              if (!(window.proplist[propname])) {
                 window.proplist[propname] = true;
                 onGlobalVarCreated(propname);
              }
        }
}
selbie
  • 100,020
  • 15
  • 103
  • 173
0

Afaik, .watch() is only SpiderMonkey (Firefox).

I played around with a polling function, I finally came up with this:

var mywatch = (function() {
    var last = {
        count: 0,
        elems: {}
    };    

    return function _REP(cb) {
        var curr = {
                count: 0,
                elems: {}
            },
            diff = {};

        for(var prop in window) {
            if( window.hasOwnProperty(prop) ) {
                curr.elems[prop] = window[prop]; curr.count++;
            }
        }

        if( curr.count > last.count ) {
            for(var comp in curr.elems) {
                if( !(comp in last.elems) ) {
                    diff[comp] = curr.elems[comp];
                }
            }
            last.count = curr.count;
            last.elems = curr.elems;

            if(typeof cb === 'function')
                cb.apply(null, [diff]);
        }

        setTimeout(function() {
            _REP(cb);
        }, 400);
    };
}());

And then use it like:

mywatch(function(diff) {
    console.log('NEW GLOBAL(s): ', diff);
});

Be aware that this only handles new globals. But you can easily extend this for the case last.count > curr.count. That would indicate that global variables were deleted.

jAndy
  • 231,737
  • 57
  • 305
  • 359
0

You cant have an event fired when some script does var v = 10, but as selbie said, you can poll the window object... I meant to suggest the same, but he beat me to it. Here's my other example... you count how many window objects are there, and execute GlobalVarCreated() function:

var number_of_globals = 0; //last known globals count

var interval = window.setInterval(function(){

   var new_globals_count = 0; //we count again
   for(var i in window) new_globals_count++; //actual counting
   if(number_of_globals == 0) number_of_globals = new_globals_count; //first time we initialize old value
   else{
     var number_of_new_globals = new_globals_count - number_of_globals; //new - old
     if(number_of_new_globals > 0){ //if the number is higher then 0 then we have some vars
         number_of_globals = new_globals_count; 

         for(var i = 0; i<number_of_new_globals; i++) GlobalVarCreated(); //if we have 2 new vars we call handler 2 times...
     }

   }

},300); //each 300ms check is run


//Other functions
function GlobalVarCreated(){}
function StopInterval(){window.clearInterval(interval);}

You can load up that code in Chrome or FF console only change: function GlobalVarCreated(){console.log("NEW VAR CREATED");} and test it:

var a = 10

b = 10

String NEW VAR CREATED is displayed 2 times.

Cipi
  • 11,055
  • 9
  • 47
  • 60