1.什麼是全域性變數和區域性變數
全域性變數:常常定義在函式外部,擁有全域性作用域,即在 JavaScript 程式碼的任何地方都可以訪問。
區域性變數:定義在函式內部,只能在函式中使用的變數,作用範圍是從函式開始到結尾,即在{}裡。
在函式內宣告的變數只在函式體內有定義,即為區域性變數,其作用域是區域性性的。需要注意的是,在函式體內宣告區域性變數時,如果不使用 var 關鍵字,則將宣告全域性變數。
<script> var str1 = "hello1"; //定義一個全域性變數 function a() { var str2 = "hello2"; //定義一個區域性變數 str3 = "hello3"; //定義一個全域性變數 }</script>
此處str1和str3是全域性變數,str2為區域性變數。
2.全域性變數和區域性變數的宣告2.1 全域性變數的宣告
在js中全域性變數宣告方式分為顯示宣告和隱式宣告。
第一種宣告方式:使用var關鍵字+變數名在函式外部宣告就是全域性變數,例如:
var bianliang = "全域性變數";
第二種宣告方式:沒有使用var關鍵字宣告,直接給變數名賦值,不管是在函式內部還是外部都是全域性變數,例如:
<script> text = "全域性變數"; function bl() { text1 = "我也是全域性變數"; var text2 = "我是區域性變數"; console.log(text2); //區域性變數只能在函式中使用 } bl() //結果:我是區域性變數 console.log(text); //結果:全域性變數 console.log(text1); //結果:我也是全域性變數 //console.log(text2); //區域性變數,在函式外使用會報錯</script>
第三種宣告方式: 使用window全域性物件來宣告,全域性物件的屬性對應也是全域性變數,例如:
window.test3 = 'window全域性物件宣告全域性變數'; console.log(test3);//結果:window全域性物件宣告全域性變數
2.2 區域性變數的宣告宣告區域性變數一定要使用var關鍵字,使用var關鍵字宣告變數時,變數會自動新增到距離最近的可用環境中。如果沒有寫var, 變數就會暴露在全域性上下文中, 成為全域性變數。如果變數在未宣告的情況下被初始化,該變數會自動新增到全域性環境。
<script> function bl() { text1 = "我也是全域性變數";//沒有使用var 為全域性變數 var text2 = "我是區域性變數"; console.log(text2); //區域性變數只能在函式中使用 }</script>
3.全域性變數和區域性變數一些常見問題 3.1全域性變數跟區域性變數重名
當全域性變數跟區域性變數重名時,區域性變數的scope會覆蓋掉全域性變數的scope,當離開區域性變數的scope後,又重回到全域性變數的scope。
<script> var str = "我是全域性變數"; function b() { var str = "我是區域性變數"; console.log(str); //結果:我是區域性變數 } b(); console.log(str);//結果:我是全域性變數</script>
當全域性變數遇上區域性變數時,怎樣使用全域性變數呢?用window.globalVariableName。
<script> var a = 1; //全域性變數 ! function b() { var a = 2; //區域性變數a在這行定義 console.log(window.a); //a為1,這裡的a是全域性變數哦! console.log(a); //a為2,這裡的a是區域性變數哦! }() console.log(a); //a為1,這裡並不在function b scope內,a的值為全域性變數的值</script>
3.2 零散變數的問題
Javascript在執行前會對整個指令碼檔案的宣告部分做完整分析(包括區域性變數),從而確定變數的作用域。所以Javascript允許在函式的任意地方宣告變數,無論在哪裡宣告,效果都等同於在函式頂部進行宣告。怎麼理解呢?看下面一個例子:
<script> var str = "我是全域性變數"; ! function b() { console.log(str); //結果:undefined var str = "我是區域性變數"; console.log(str); //結果:我是區域性變數 }()</script>
為什麼不是: 我是全域性變數 和 我是區域性變數?原因很簡單:對JavaScript而言,只要變數是在同一個範圍(函式)裡,就視為已經宣告,哪怕是在變數宣告前就使用。上面的程式碼相當於:
<script> var str = "我是全域性變數"; ! function b() { var str; //系統自動賦值為 str = undefined console.log(str); //結果:undefined var str = "我是區域性變數"; console.log(str); //結果:我是區域性變數 }()</script>
3.3. 變數釋放問題
請看下面的程式碼:
<script> var a = "hello"; //全域性變數 window.b = "word"; //全域性變數 delete a; delete b; console.log(typeof a); //結果:string console.log(typeof b); //結果:undefined ! function b() { var c = 1; //區域性變數 d = 2; //全域性變數 delete c; delete d; console.log(typeof c); //結果:number console.log(typeof d); //結果:undefined }()</script>
結論:
使用 var 建立的變數不能使用 delete 釋放記憶體。不使用 var 建立的變數可以使用 delete 釋放記憶體。總結:在過程體內(包括方法function(){},物件Object o={})內的物件)加var保留字則為區域性變數,其他情況下都是全域性變數(無論是否使用var。不進行宣告而直接使用全域性變數會報錯(可以隱式宣告),而區域性變數先使用後宣告則不會報錯,只是值為undefined。全域性變數跟區域性變數重名時,區域性變數的範圍會覆蓋掉全域性變數的範圍,當離開區域性變數的範圍後,又重回到全域性變數的範圍。(若想指定是全域性變數可以使用 window.globalVariableName。Javascript允許在函式的任意地方宣告變數,無論在哪裡宣告,效果都等同於在函式頂部進行宣告。使用 var 建立的變數不能使用 delete 釋放記憶體,其他方式建立的變數可以使用 delete 釋放記憶體。一般來說全域性變數所帶來的 bug 問題非常多,所以最好儘量少用全域性變數。另外,宣告變數最好帶 var, 不應使用帶 var 的鏈式賦值,在函式體內定義變數時,最好把變數宣告放在頂部,防止出現變數沒有被定義就被使用的邏輯錯誤。