JS 基礎回顧 - 全域變數與區域變數
在上一篇 變數與資料型別 中有介紹到變數,而變數還分為全域變數與區域變數,本篇將會介紹兩者的差異。
區域變數
首先用個函式來算一下梯形的面積:
1 | function areaTr (upBase, downBase, height) { |
上面的這一段沒什麼問題,如果在後面再加上一段 console.log(result)
的話,會發生什麼事?
1 | function areaTr (upBase, downBase, height) { |
結果第二個 console 會出現錯誤,錯誤訊息是 result is not defined。
為什麼找不到 result 呢?
首先要先了解一個原則,變數的最小有效區域只在函式中。
而在這個例子中,在函式裡透過 var 指定變數,第一個 console 執行完以後,變數就被用掉消失了,第二個 console 當然就找不到。
以上是一個區域變數的範例,而區域變數的好處是執行完後變數就會消失,可以節省記憶體。
全域變數
接著來看看在函式裡沒有透過 var 來宣告變數會怎樣。
在上面提到區域變數的範例中,原本第二個 console 不能執行。
那麼把 var 拿掉後:
1 | function areaTr (upBase, downBase, height) { |
結果第二個 console 可以執行了!?
這是因為如果不是由 var 宣告的變數,都會是全域變數。
所以即使變數 result 是在函式中宣告,但是因為沒有透過 var,所以一樣是全域變數。
而不在函式裡的變數,會一直都在。雖然一直都在可以隨時存取,但是這樣做比較浪費記憶體。
所以除非必要,否則在函式內的變數,都盡量透過 var 來宣告。
來看看如果計算梯形面積的函式,想要執行第二個 console 的話,還有以下方法:
透過 var 宣告變數,但不給值
在函式前再透過 var 宣告變數,但不給值。
1 | var result; |
如果是兩個變數都透過 var 宣告會是如何?
1 | var result; |
第一個 console 一樣可以得到 “梯形面積是1400”,而第二個則是得到 undefined。
由於變數在函式中,以及透過 var 來宣告,所以符合區域變數的規範。
所以第一個 console 執行完,雖然最前面有透過 var 宣告變數,是一個全域變數,但是並沒有值,所以是 undefined。
這時候如果給它值,例如:
1 | var result = 500; |
基本上透過 var 來宣告,這兩個變數就可以視為兩個不同的東西了,要直接改變數的名字也印的出來結果。
提升
提升 (hoisting) 在 JavaScript 中又是一個坑。這在後面的一篇會提到,這邊則是稍微講一下。
在一般的情形下,執行以下的程式碼,其結果會是2
1 | var a = 2; |
那麼如果在變數的前面也加上 console.log
呢?
1 | console.log(a); |
結果會是 undefined
跟 2
,原因是 JavaScript 在執行時會是一行一行的執行,所以在執行第一行時找不到 a ,所以會是 undefined。
那麼在 function 中作這樣的事會是怎樣呢?
把呼叫執行的 hi()
放在 function 的前面
1 | hi(); |
結果一樣可以印出 hello
!!!
這是因為在 JavaScript 中,function 會優先執行,所以會作一個 hoisting,所以一樣可以執行。
但最好還是不要這樣作