如何快速定位不小心暴露到全局的變量


今天在查看頁面控制台的時候,無意中看到了一個暴露到全局的變量 i,全局變量是不會被壓縮工具壓縮成簡寫的字母,這個被頻繁使用的變量名暴露到全局也是個相當大的隱患,可能一個不小心就覆蓋了第二次暴露到全局的同名變量。

剛開始我就懷疑是自己出現了這樣愚蠢的錯誤:

function A() {
    // 在一個函數中多次用到了 for 循環,為了節省變量,都是用了變量 i
    for(var i = 0; ...) {
        //...
    }
    for(i = 0; ...) {
        //...
    }
    for(i = 0; ...) {
        //...
    }
}

結果在某次拆分函數的時候,忘記定義:

function A(){
    for(var i = 0; ...) {
        //...
    }
    for(i = 0; ...) {
        //...
    }
}
function B(){
    for(i = 0; ...) {
        //...
    }
}

這個時候,變量 i 在 B 函數執行的時候就暴露到了全局。抱着這樣的懷疑,我搜索了 50 多個模塊的代碼,一無所獲...此時,我依然十分懷疑是自己的程序哪里疏忽了,全局搜索 i =i++,五分鍾過去了,未果...

找到這個變量

如果這個變量名叫做 fuckIE,分分鍾全局搜索就出來了,類似這種簡短的常用的變量,着實讓人頭疼了好一會兒。后來想到了這個方案:

Object.defineProperty(window, "i", {
    get : function(){ return window.i; },
    set : function(newValue){ debugger;window.i = newValue; },
    enumerable : true,
    configurable : true
});

在全局定義變量 i 的時刻,打一個斷點,然后 F10 往前走一步,果然,在控制台右側的 Call Stack 中找到了端倪!

這個變量是從第三方組件中(offline組件,使用相當頻繁的一個組件)暴露出來的,估計出錯的方式同我上面的描述差不多,拆分函數的時候忘記重新定義變量 i。

當然還有更快的方式:

window.__defineSetter__('i', function(){ debugger })

不挖坑才是最好的解決方案

1. 使用 use strict;

在嚴格模式下,這種問題暴露無遺,每個函數內都加上 use strict;,雖然在語言上有所限制,但是低級錯誤一定不會出現,因為嚴格模式會給你報錯!

2. 使用 jslint/jshint 等 js 分析工具

這些東西除了配置上較為繁瑣,用起來還是很順手的,做過配置的錯誤都會直接在 IDE 上標紅顯示出來,很容易發現問題,但是不建議一個項目中途使用,因為代碼習慣的問題,很多地方被 js 分析工具作為錯誤拋出來,改動量是相當大的。

我有次也犯了個比較隱晦的錯誤:

$(window).on('click', function(evt){
    var target = event.target.nodeName.toLowerCase();
    if(target !== 'ul'){
        //...
    }
});

在 IE 和 Chrome 下,代碼跑得好好的,但是到了測試較少的 FF 下,問題出來了,event is not defined.,IE 和 Chrome 是支持 window.event 抓取當前事件對象的,而 FF 不支持,所以每次點擊頁面上都會報錯。。。

諸如此類的問題,在我們的平時編碼之中不勝枚舉,所以有一個編碼規范作為強約束是十分有必要的!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM