--- tags: JavaScript --- # 變數 由於網頁程式中會執行大量的程式腳本,不論你分割開來在不同的檔案中,最終在 script 標籤引入或是打包後都會變成共享同一個全域範疇,這時若發生非預期的 hoisting 或是全域污染,其導致的錯誤將會變得相當顯著,並且難以 Debug。 `const` 和 `let` 都是 **block-scoped**,也就是僅在限定的 `{}` function 內有效。 ```javascript if (true) { const a = 0 } console.log(a) // ReferenceError: a is not defined ``` ## `const` `const` 用於宣告**固定不變的常數**,變量指向**記憶體的位址不可以變動**,改變其值時會跳錯: ```javascript const a = 1 a = 2 // TypeError: Assignment to constant variable. ``` 但若其變數為 Array 或是 Object,在修改內容時並不會跳錯,因為這兩種都是屬於 reference type,所以變化的是內容時,本身的位置沒有改變,就不會跳錯。 ```javascript const a = [1, 2] a.push(3) // [1, 2, 3] a = [4, 5, 6] // TypeError: Assignment to constant variable. ``` ## `let` 為何要使用 `let` 而非 `var` ? 1. `var` 的作用域 scope 比 `let` 還要大,蛋越大跨出步伐時越容易扯到蛋。 ```javascript for ( var i = 0 ; i < 3 ; i++ ) { setTimeout( () => { console.log(i) }, 1000 ) } // 3 3 3 想不到吧 ``` `setTimeout` 會去註冊一個 callback function,1 秒後執行。在 scope 沒有管控好的狀況下,loop 裡頭的異步事件會去註冊起來,且使用 var 宣告的變數仍然會直到 i = 3 時才停止,並在一秒之後,分別被印出這些奇妙的東西。 ## 參考資料 - [Learn JavaScript in Y minutes](https://learnxinyminutes.com/docs/javascript/) - [JavaScript: Understanding the Weird Part](https://pjchender.blogspot.com/2017/06/javascript-understanding-weird-part.html)