標籤:
以前僅僅知道在script標記中直接聲明變數,這個變數便是一個全域變數,在整個頁面上都可以訪問到(如代碼-1)。曾經很長一段時間裡讓我感到想到困惑,在頁面js比較多的情況下,多個檔案引入時很可能會有變數被重新申明賦值,於是有了 這樣的研究。
代碼-1:
<script> var a ="1";</script>
隨著學習的深入,後來發現其實代碼-1中聲明變數的方式,實際範圍是window,所以變數(函數)都被擴充到了window這個對象上。
代碼-2:
var a = 1;console.log(window.a); // 1
再後來發現原來這個叫 execution context(執行環境),於是就有了下面的遇見。
對於一個有C#或Java或其他語言背景的朋友,對變數的範圍應該是這樣的:
在哪個範圍聲明就在哪個範圍結束(一個成對的{中)。
代碼-3:
<script> function test(){ if(true){ var a=1; } console.log(a);//undefined ? }</script>
對上述代碼的執行結果推測應該是undefined吧。可在JavaScript中真的是這樣嘛?學習了這麼久,個人感覺這是一門能顛覆人生觀的程式設計語言,不能太相信直覺。試了試,發現果然不能用C#的眼光看待JavaScript。
在JavaScript中if語句中的變數申明,會添加到當前執行環境中。代碼-3中的執行環境為test這個函數,所以變數a,在整個test函數內可以訪問。當函數執行完成後才進行銷毀。而函數test的執行環境是什麼呢?呵呵,當然是window。
這個很重要,因為在JavaScript中定義的變數範圍並不是在某個塊裡,而是在執行環境中(如window,獨立的function)。
代碼-4:
<script> function test(){ function testnew(){ var a = 1; } console.log(a); // undefined }
testnew()//error ,testnew is not defined.</script>
上述代碼共有3個執行環境,分別是window、test、testnew。雖然testnew的執行環境為test,但在test裡並不能訪問testnew中聲明的變數。同理window中不能訪問test中聲明的變數。這裡需要注意的是,除function外,其他的區塊層級元素不是獨立執行環境,如:if,for,try等。所以,呵呵,在if,for,try中聲明的變數在同一個執行環境裡是可以訪問的。
想想JavaScript給人的感覺是多麼“奇葩”(尤其是我們這樣的C#程式員),範圍居然叫執行環境,萬能圍牆大括弧居然不再萬能。
javascript範圍學習筆記