2011-02-23 52 views
4

我想监视在Javascript中创建新的全局变量,以便在任何时候创建全局变量时触发一个事件。如何检测新的全局变量的创建?

我听说过watch()函数,但它只是用于观察特定的变量名称。我想要一个猫。

+0

你能告诉我们,为什么? – Starx 2011-02-23 07:50:54

+0

我正在编写一个框架,它将任何变量插入到全局名称空间中,并将它们放入数据结构中以进行跟踪。 – 2011-02-23 07:56:10

+0

也许这篇文章会激发一些想法http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers – maerics 2011-02-23 08:00:18

回答

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

'foreach'不是有效的关键字!将'if(window.proplist)'放在'for'循环之外。 – Raynos 2011-02-23 08:06:22

+0

在JavaScript无可奉告!不会给你-1,解决这个问题。对于(var窗口中的变量名)''会起作用。 – Cipi 2011-02-23 08:06:28

+0

糟糕...好赶上家伙。固定在上面。海报只有没有赚到足够的stackoverflow点我实际测试我的答案(或优化!)。 :) – selbie 2011-02-23 08:08:32

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

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倍。

2

如果你已经知道这名污染您的全局命名空间(见Intercepting global variable definition in javascript),你可以使用这一招找出它实际上发生:

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

一定有你的开发工具开放当你运行这个。 显然,只有当您的浏览器支持__defineSetter__时才有效,但对于现代浏览器来说则是如此。另外,请不要忘记在完成后删除您的调试代码。

找到here