如何检测新的全局变量的创建?

时间:2011-02-23 07:44:15

标签: javascript javascript-events global-variables

我想监视在Javascript中创建新的全局变量,这样,无论何时创建全局变量,都会触发事件。

我听说过watch()函数,但这只是为了观察特定的变量名。我想要一个收获。

4 个答案:

答案 0 :(得分:3)

我不知道如何在创建var后立即“按需”完成此工作,但我可以建议一种轮询方法。在浏览器窗口中,所有全局变为全局“窗口”对象的成员。 (因为从技术上讲,“窗口”是“全局对象”)。所以你可以做类似以下的事情:

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

答案 1 :(得分:2)

如果您已经知道哪些名称污染了您的全局命名空间(请参阅Intercepting global variable definition in javascript),您可以使用此技巧找出 实际发生的时间:

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

确保在运行此工具时打开您的开发人员工具。 显然只有在您的浏览器支持__defineSetter__时才有效,但现代浏览器也是如此。另外,请不要忘记在完成后删除调试代码。

找到here

答案 2 :(得分:0)

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扩展它。这表明全局变量已被删除。

答案 3 :(得分:0)

当某个脚本执行var v = 10时你无法触发事件,但正如selbie所说,你可以轮询窗口对象......我的意思是建议同样的,但他打败了我。这是我的另一个例子......你计算有多少窗口对象,并执行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次。