對於剛接觸前端開發不久的人來說,可能會對var、let 與 const 的差異略懂略懂,但又說不太出三者實際哪裡不一樣。
在 JavaScript ES6 中,let、const 取代了 var 作為新的宣告變數時使用的關鍵字,讓變數在被宣告時,可以更加嚴謹,因此在現行的專案中,大部分的人都是使用這來個關鍵字來宣告變數居多,不太會有需要使用到 var 的機會。
既然不太會使用到,為什麼我們依然要花時間理解,透過這三者來宣告變數的差異呢?這會有幾個主要的原因:
- 了解let 與 const 是為什麼解決什麼問題而存在
- junior front-end developer 必考的面試考題
- 不少舊的套件還是使用 var 作為範本
- 許多經典的前端書籍還維持在 var 的使用階段
- 未來你有可能會經手、接管、維護舊專案
因此,花一點時間來了解這個議題絕對很值得,接下來的內容中,主要會以下幾點來進行討論:
- 變數是否可以被重複宣告
- 變數是否可以被重新指值
- 變數作用域差異
- 變數 Hoisting 行為時的報錯訊息不同
- 變數是否強制在宣告時指定值
如果你還不曉得什麼是 ES5、ES6 的話,可以參考這篇文章:
變數是否可以重複宣告(redeclare)
ES6 以前還沒有 let、const 前,如果使用 var 關鍵字對同一個變數重複宣告是合法的,並不會報錯。
使用 var 重複宣告但不報錯的原理,就很像是我們可以針對同一個 CSS 類別下不同的樣式,而最下方的程式碼會覆蓋掉最上面的,但並不構成錯誤。
然而重複宣告變數,可能會造成開發者要取用變數時,很容易取到錯誤的值,程式碼會變得不好維護,所以在 ES6 以後,新增了 let、const 關鍵字作為替代。
我們會發現,在還沒有執行到 console.log(price) 時,程式碼就因為 price 變數被重複宣告而出現錯誤無法繼續執行。
同理,既然是為了修正以前 var 可以被重複宣告所造成的錯誤, const 關鍵字同樣不能拿來重複宣告變數。
結論:var 可以被重複宣告,但是 const、let 不行。
變數是否可以被重新指值( reassign / mutate )
有時候為了要在函式中更新全域變數中的值,我們會在函式中重新指定一個新的值給全域變數。
但有時候我們不想要讓已經被宣告的變數,可以輕易地被改到值,這時候我們就可以使用 const 關鍵字來宣告變數。
使用 const 關鍵字可以避免一個變數重新被指定新值,如果有這樣的狀況的話,瀏覽器就會報錯:「Uncaught TypeError: Assignment to constant variable.」
結論:如果在宣告變數以後,還會有需求要重新指定值,那就使用 let 宣告變數;如果是固定的資料,像是資料夾位置、API 路徑等不能被輕易改動的內容,就需要使用 const 關鍵字來宣告。
變數作用域差異
作用域的差異可以說是 ES6 與 ES6 以前差異最多的部分,對於初學者來說,需要花一段時間來了解。
在 JavaScript 中變數有效的範圍,也就是可以被取用的範圍稱為作用域(Scope)。
以 var 來說,var 的作用域分為全域作用域及函式作用域,一個變數是否能被取用到,是以 function 來切分的。
在函式中想要讀出 a 變數值時,會優先查找函式內是否有名為 a 的變數,如果沒有的話才會向外查找。
但在 showVariable()函式中,已經有一個變數叫做 a 了,所以讀出來的結果就是「區域變數」。
但如果在函式外讀取,是取不到函式內變數 a 的值,只能取到做外層帶有「全域變數」值的 a 變數。
這裡看起來與 let、const 的使用情境無太大差異,讓我們再來看看另一個範例:
顯然在這個範例中,只用大括號包住的宣告,並沒有辦法達到區域作用域的功能,反而將 a 的值都覆寫過去了,讓兩邊的印出來的值都是「區域變數」,光這一點就能判斷 var 的作用域只會在全域及函式中出現。
而且只要是透過 var 宣告過的變數,便會成為全域屬性,造成全域污染的問題。
現在如果用 let 來取代 var 來宣告一樣的變數會發生什麼事呢?
這一個範例跟剛剛使用 var 宣告沒有兩樣。
但是我們可以發現 let 在 { } 中是可以自行創建出作用域的!
由此可知我們可以透過上方範例了解到,let、const 的作用域與 var 不一樣,屬於全域、區塊作用域。
變數 Hoisting 時的行為不同
let、const 作為 ES6 以後的語法,很嚴格的禁止「宣告前可以被取到值」的行為:
然而如果透過 var 來宣告的話:
會發現透過 var 宣告的變數不會報錯,而是出現 undefined 的值。
這裡做個小結:這三者都會有 hoisting 的行為,在宣告前就取用變數時,var 僅會回傳 undefined,但是因為 let、const 較嚴謹,所以會帶有錯誤訊息,MDN 文件稱這個現象為 TDZ(Temporal dead zone)。
由於 hoisting 行為需要一點篇幅解釋,希望之後在利用其他篇幅來跟大家介紹何謂 hoisting,又因這一篇為 let、const及var 的差異比較,故不多贅述。
變數是否強制在宣告時指定值
const 在宣告時一定要指定值,不然會報錯。
但在使用 var 與 let 時,可以不用先指定值,可以後續在重新指定,這是基於透過 const 宣告的變數,會成為常數,所以不帶有重新指定值的特性。
基本上 let、const 與 var 的差異了解大概到這,希望下次碰到這個問題時,可以更有自信的講述這三者的差異性,即便開發上不太會用到,卻是能更了解這門語言的機會。
相信透過這篇文章,大家可以更加了解let、const 與 var 的差異,關於網頁開發你有沒有什麼問題想要跟我分享的呢?歡迎你在下方留言與我分享。
希望今天的文章有幫助到正在閱讀的你,如果你喜歡我的文章的話,可以留下你的愛心或是收藏我的文章,也或者可以點選「贊助」,你的一杯咖啡絕對是我持續寫下去的動力!或是透過拍拍手,用你小小的行動支持我的創作!
我是Vivian,我們下次見。
關於我:
一名從英文系畢業的前端工程師,喜歡閱讀、寫東西及自我成長。