在javascript中,作用域一般分3種,有塊作用域。 3種作用域分別為:1、全域作用域,是聲明在所有函數之外的全域變數的作用域;2、局部作用域,是聲明在函數內的局部變數的作用域;3、區塊層級作用域,是區塊級變數宣告語句開始到區塊結束之間的區域。
本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
變數的作用域(scope),指的是變數在腳本程式碼中的可讀、寫的有效範圍,也就是腳本程式碼中可以使用這個變數的區域。在ECMAScript6 之前,變數的作用域主要分為全域作用域、局部作用域(也稱為函數作用域)兩種;
在ECMAScript6 及其之後,變數的作用域主要分為全域作用域、局部作用域和區塊級作用域這3 種。
對應作用域的變數分別稱為全域變數、局部變數和區塊層級變數。
全域變數宣告在所有函數之外;
#局部變數是在函數體內宣告的變數或是函數的命名參數;
區塊級變數是在區塊中宣告的變數,只在區塊中有效。
變數的作用域跟宣告方式有著密切的關係。使用 var 宣告的變數的作用域有全域作用域和函數作用域,沒有區塊級作用域;使用 let 和 const 宣告的變數有全域作用域、局部作用域和區塊級作用域。
注意:嚴格意義的全域變數都屬於window 物件的屬性,但let 和const 宣告的變數並不屬於window 對象,所以它們並不是嚴格意義上的全域變量,在此僅從它們的作用域這個角度來說它們是全域變數的。
由於var 支援變數提升,所以var 變數的全域作用域是對整個頁面的腳本程式碼有效;而let 和const 不支援變數提升,所以let 和const 變數的全域作用域指的是從宣告語句開始到整個頁面的腳本程式碼結束之間的整個區域,而宣告語句之前的區域是沒有效的。
同樣,因為var 支援變數提升,而let 和const 不支援變數提升,所以使用var 宣告的局部變數在整個函數中有效,而使用let 和const 宣告的局部變數從宣告語句開始到函數結束之間的區域有效。
需要注意的是,如果局部變數和全域變數同名,則在函數作用域中,局部變數會履蓋全域變量,即在函數體中起作用的是局部變數;在函數體外,全域變數起作用,局部變數無效,此時引用局部變數將出現語法錯誤。
對區塊級變數來說,其作用域是區塊級變數宣告語句開始到區塊結束之間的區域。在區塊開始到區塊級變數聲明語句之間的區域為“暫時性死區”,在這個區域,區塊級變數沒有效。
另外,在非嚴格運行模式中,變數可以不需要聲明,這些沒有聲明的變量,不管在哪裡使用都屬於全域變數。通常不建議變數不宣告而直接使用,因為這樣有可能會產生一些不易發現的錯誤。
【範例 1】變數的作用域範例。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>变量作用域示例</title> <script> var v1 = "JavaScript"; //全局变量 let v2 = "JScript"; //全局变量 let v3 = "Script"; //全局变量 scopeTest(); //调用函数 function scopeTest(){ var lv = "aaa"; //局部变量 var v1 = "bbb"; //局部变量 let v2 = "ccc"; //局部变量 if(true){ let lv = "123"; //块级变量 console.log("块内输出的lv = " + lv); //123 } console.log("函数体内输出的lv = " + lv); //aaa console.log("函数体内输出的v1 = " + v1); //bbb console.log("函数体内输出的v2 = " + v2); //ccc console.log("函数体内输出的v3 = " + v3); //Script //v4为全局变量,赋值在后面,因而值为undefined console.log("函数体内输出的v4 = " + v4); } var v4 = "VBScript"; //全局变量 console.log("函数体外输出的lv = " + lv); //① 报ReferenceError错误 console.log("函数体外输出的v1 = " + v1); //JavaScript console.log("函数体外输出的v2 = " + v2); //JScript console.log("函数体外输出的v3 = " + v3); //Script console.log("函数体外输出的v3 = " + v4); //VBScript </script> </head> <body> </body> </html>
上述腳本程式碼分別宣告了 4 個全域變數、3 個局部變數和 1 個區塊層級變數。在 scopeTest 函數體外,變數 v1、v2、v3 和 v4 為全域變數;在 scopeTest 函數體內,lv、v2是全域變數;在 if 判斷區塊中,lv 是區塊級變數。
我們看到,局部變數v1 和v2 與全域變數v1 和v2 同名,在scopeTest 函數體內,局部變數v1 和v2 有效,因而在函數體這2 個變數的輸出結果分別為「bbb 」和「ccc」;在函數體外,全域變數v1 和v2 有效,因而在函數體外,這2 個變數的輸出結果分別為「JavaScript」和「JScript」。
另外,區塊級變數lv 和局部變數lv 同名,在if 判斷區塊中,區塊級變數lv 有效,因而在區塊中輸出的結果為“123”,而在區塊外,局部變數lv有效,lv 變數的輸出結果為「aaa」。
另外,全域變數v3 和v4 在函數體中沒有被覆蓋,因而輸出的是全域變數的值,所以v3 在函數體內和體外的輸出結果都為“Script”,而v4 變數的賦值在函數呼叫的後面,因而在函數體中的v4 輸出結果為“undefined”,而在函數體外的輸出是在宣告之後,所以結果為“VBScript”。 lv 是局部變量,因而在函數體外存取會報「ReferenceError」錯誤。
上述程式碼在 Chrome 瀏覽器中運作後,開啟瀏覽器的控制台,可以看到圖 1 所示的輸出結果。
圖1:① 處程式碼註解前控制台輸出結果
圖 1 圖示報第 26 行程式碼(即範例 1 ① 處註解的程式碼)中的 lv 沒有定義的參考錯誤,這是因為 lv 變數為局部變量,離開函數後無效。將這行程式碼註解後再執行,此時開啟瀏覽器控制台可看到圖 2 所示結果。
圖2:① 處程式碼註解後控制台輸出結果
從圖2 可看到,區塊級變數在區塊內覆蓋局部變量,局部變數在函數體內覆蓋全域變量,沒有被覆蓋的全域變數在函數體內、外都有效。思考:為什麼在函數體內 v4 變數的輸出結果是「undefined」而不會報錯?
更多程式相關知識,請造訪:程式設計影片! !
以上是javascript中作用域一般分幾種? js中有沒有區塊作用域?的詳細內容。更多資訊請關注PHP中文網其他相關文章!