# [JavaScript] 談var、let、const差異之var你這個矯情的賤人 ###### tags: `JavaScript`, `JS`, `var`, `let`, `const` 寫在JS的旅程上,宣告變數這種最基本的起手式,勢必像我這種程式麻瓜在找資料或看別人的code,一定常看到`var`、`let`、`const`這宣告變數的三劍客。 ![](https://i.imgur.com/6UNob0q.jpg) 看似可愛又很有用的工具,殊不知裡面有深不見底的可怕秘密,今天我們就一起上車探索`var`、`let`、`const`這三個宣告變數的差異吧(老司機帶帶我~) ![](https://i.imgur.com/ZTlZ7J8.png) 在談宣告變數前,先幫大家簡單科普兩個變數種類。 - **全域變數 (Global Variable)** - **區域變數 (Local Variable)** 簡單而言兩者差異在於宣告變數的位置可決定他屬於下列兩者其一的變數,而位置指的是「作用域」。 ![](https://i.imgur.com/rrO3B5K.png) 從上圖中,我們在外圍宣告一個變數`a`,另於`function test()` 內另宣告變數`b`,然後分別透過`console.log`印出`test()`, `a`, `b`。 可發現`function test()`及`a`都可印出我們賦值的字串,但`b`就無法存活在windows上,最主要原因是變數`b`僅被宣告於`function test()`內,一旦出去這個區域,沒了宿主(跟猛毒一樣嗎XD),就會印出錯誤訊息。 ![](https://i.imgur.com/CUi9o0k.jpg) 好的,回到主題,我們先從`var`開始說起。 ## `var` 雖說現在學JS在宣告變數都會叫麻瓜們用`let`及`const`,但ES6以前的世界,宣告變數都會用`var`一招打天下,實際上進入職場,可能還常看到`var`到處放肆XDD,當然另一部份也可能是ES6支援的普及程度,因此我們還是得認識一下`var`這個矯情的賤人XDD 其實`var`宣告變數與`let`的方式並無兩樣,若套用剛剛全域、區域變數的範例。 ![](https://i.imgur.com/ptSBSpe.png) 但,畢竟`var`是個矯情的賤人,所以當然不會讓你這麼好過,哈哈! 當`var`使用於一些區塊語法時,會情不自禁感染全域變數,我們透過以下範例來看。 ![](https://i.imgur.com/lCKefmH.png) 從上圖可看出,當我們用`var`在`for`迴圈中宣告變數時,當印出迴圈的值後,外面再印一次變數`i`時,值會變成4,這也證明原來在`for`迴圈用`var`宣告的變數`i`會把在全域的變數`i`也賦值,因此可印出值。 反之,用`let`宣告的變數則不會感染全域的變數`i`,當印出全域的變數`i`時,就會出現「***i is not defined***」。 另外,`var`還有一個討厭的屬性是可以重複宣告變數,話不多說直接看下圖。 ![](https://i.imgur.com/N831mME.png) 從圖中可看出,用`var`重複宣告兩次變數`a`,但可正常印出值。而用`let` 宣告則會出現「已經宣告過變數`a`」,這也是當我們程式碼越來越多時,可能會造成的困擾,因為有可能會忘了在哪個地方曾經宣告過同名稱的變數,以致前面的函式被覆蓋新值而造成錯誤。所以ES6後,都會希望以`let`及`const`宣告變數,以避免上述狀況。 講完這個矯情的賤人後,我們來看看`let`吧~ ![](https://i.imgur.com/83DgL6s.jpg) ## `let` 在ES6後,感謝蒼天讓我們有更嚴謹的宣告變數方法,就是我們的`let`哥~ 其實如同跟`var`宣告變數的方式是雷同,畢竟說到底`var`還是算`let`及`const`的大哥,大哥是對的~ ![](https://i.imgur.com/0dfhXFC.jpg) 簡單說明`let`宣告變數的特性, - **作用於「區塊作用域(Block Scope)」** - **禁止於同個區塊作用域重複宣告** 其實在我們介紹`var`時也有比較過,這邊我們就不再贅述。 不過當我們同時用`let`及`var`宣告同一個變數於同個區塊作用域時,也是會宣告失敗的,可看以下範例。 ![](https://i.imgur.com/UO86y4t.png) 但如果在不同作用域時,則不會互相影響。 ![](https://i.imgur.com/ezgPPBc.png) 如果可以理解的話,那最後來談談`const`吧~ ## `const` 比起`let`,`const`又是更嚴謹的宣告變數,其實`const`是「常數(Constant)」縮寫而來的。所以顧名思義`const`就是宣告常數的意思。 而常數在數學中泛指一個數值不變的值。無論天塌地崩、世界末日,被`const`宣告變數的值是不會變的,就跟我的帥一樣(大誤XDDD) 不過除此之後,`let`有的特性其實`const`也都會有。 所以`const`宣告常用於已被定義的數值,像是圓周率,或是身份證字號等,這也便不會因為程式關係,不小心更動到使用者原始的數據,可參考以下範例。 ![](https://i.imgur.com/M2JHwqY.png) 上圖我們嘗試要給`myID`賦予新的字串,但系統會因為`myID`是常數關係而出現賦值錯誤的訊息。 ## 總結 雖然開頭一直說`var`壞話,但我們仍必須正視他,畢竟JS開發歷史非常悠久,還是會有很多公司的原始碼會使用`var`宣告變數,所以我們還是必須得了解他。 整理一下上述說明, - **`var`: 是「可」重複宣告相同變數,區塊語法用`var`宣告可能會感染全域變數。** - **`let`: 是「不可」重複宣告相同變數,其作用域僅在「*區塊作用域(Block Scope)*」,一旦離開則會無作用,顯示無定義。** - **`const`: 特性同`let`,但更嚴謹。一旦變數宣告為常數後,則無法再賦新值。** 以上,僅是小弟非常初淺的說明,畢竟自己也是個程式麻瓜,還在初學階段,因此若有任何錯誤,歡迎各路大大們指教及提醒,感謝。 ### 參考資料: - [[JS學徒特訓班] JavaScript ES6 : var, let, const 差異](https://codinggirl.timelog.to/a174653905) - [你不可不知的 JavaScript 二三事#Day7:傳統 var 關鍵字的不足](https://ithelp.ithome.com.tw/articles/10203548)