【JavaScript】01 - var, let, const 的差別

事隔多年終於開始來補前端的深度了,那就先研究變數宣告:var, let, const 的差別吧。

先講結論:差別在於變數的生命週期

關鍵字作用範圍可修改
(無)全域v
var函式v
let區域v
const區域x

再來看程式範例

一、全域:不使用關鍵字

沒毛病,一經宣告在所有函式裡都可以引用的,以下範例使用無關鍵字宣告。

改成使用 var 或 let 宣告也是得到一樣的效果,因為 var, let 宣告在最外面,可以當作整個js 都是一個同一個區域,當然作用範圍就在整個js 檔。

但是要注意,如果在區域內宣告無關鍵字變數,外層也沒有宣告過此變數,則雖然他在區域內,但範圍還是會變成全域,如下:

注意到了嗎,既使value1 是宣告在print 方法內部,但因為外面沒有宣告而變成全域變數,所以console.log 也能抓到值 = 50。
另外值得注意的是,如果在第二行將value1 的宣告改為 var 或 let,第八行的console 就會因為變數生命週期的改變跳出 undefined 的例外狀況

二、函式:在function 內宣告

在function 裡面可以再宣告function,而如果子function 裡面有宣告跟外面一樣的變數,會在子function 的範圍內,暫時取代外面的變數。而離開子function 後,又會回復成父function的值。但在function 外面 存取會發生錯誤 (第15行)。

有趣的是,因為範圍是在整個function 中,經過JS 的變數提升Hoisting (在執行之前會先定義好function 內的 var),所以先取用變數也只會顯示undefined。

但將var 改為let 就會直接錯誤,若將let 插入到第二列,或是將print2 移到第九列,一旦經過宣告後,就可以正常執行。

另外一個需要注意的是var 的函式範圍,參考下圖:

number1, number2 都宣告在if 的範圍裡,if 裡面的console.log 可以抓到兩個變數。而跑到if 外面時,宣告為let 的number2 已經結束生命週期,故在if 外面抓不到此變數會產生Error。

三、區域:影響該區域,以外的地方無法存取。

區域的範例也就是上面let number2 的狀況,只要脫離宣告的區域就會結束生命週期,這邊就不測試了。

 

故結論為:
JavaScript 比較有彈性,與後端的程式語言不同。但若寫程式稍不注意,就可能會影響到外部,產生非預期的結果/錯誤。
盡量使用let 並依照後端的習性來宣告、使用變數,可以降低意外的發生。

References:
https://tw.alphacamp.co/blog/javascript-var-let-const
https://www.w3schools.com/js/js_let.asp