2011-02-23 51 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