Как обнаружить создание новых глобальных переменных? - PullRequest
4 голосов
/ 23 февраля 2011

Я хочу наблюдать за созданием новых глобальных переменных в Javascript, чтобы при каждом создании глобальной переменной вызывалось событие.

Я слышал о функции watch (), но она предназначена только для просмотра определенных имен переменных. Я хочу поймать.

Ответы [ 4 ]

3 голосов
/ 23 февраля 2011

Я не знаю, как сделать эту работу "по требованию", как только создается переменная, но я могу предложить метод опроса. В окне браузера все глобальные становятся членами глобального «оконного» объекта. (Поскольку технически «окно» является «глобальным объектом»). Таким образом, вы можете сделать что-то вроде следующего:

1) перечислить все свойства в окне

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

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

2) Установить таймер, чтобы периодически "опрашивать" окно новых свойств

setInterval(onTimer, 1000);

3) Просыпаться по таймеру обратного вызова и искать новые реквизиты

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

        for (propname in window) {

              if (!(window.proplist[propname])) {
                 window.proplist[propname] = true;
                 onGlobalVarCreated(propname);
              }
        }
}
2 голосов
/ 11 января 2013

Если вы уже знаете, какие имена загрязняют ваше глобальное пространство имен (см. Перехват определения глобальной переменной в javascript ), вы можете использовать этот трюк, чтобы выяснить , когда действительно происходит:

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

При запуске этого приложения обязательно откройте инструменты разработчика.Очевидно, работает, только если ваш браузер поддерживает __defineSetter__, но это верно для современных браузеров.Кроме того, не забудьте удалить код отладки после завершения.

Найдено здесь .

0 голосов
/ 23 февраля 2011

Вы не можете запустить событие, когда какой-то сценарий делает var v = 10, но, как сказала Селби, вы можете опрашивать объект окна ... Я хотел предложить то же самое, но он меня опередил. Вот мой другой пример ... вы считаете количество оконных объектов и выполняете функцию GlobalVarCreated ():

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

Вы можете загрузить этот код в консоли Chrome или FF, только изменив: function GlobalVarCreated(){console.log("NEW VAR CREATED");} и протестировав его:

var a = 10

b = 10

Строка NEW VAR CREATED отображается 2 раза.

0 голосов
/ 23 февраля 2011

Afaik, .watch() - это только SpiderMonkey (Firefox).

Я поиграл с функцией опроса, я наконец-то придумал это:

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

И затем использую его как:

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

Имейте в виду, что это обрабатывает только новые глобальные переменные.Но вы можете легко расширить это для случая last.count > curr.count.Это будет означать, что глобальные переменные были удалены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...