# var、let、const 的差異? 為解決ES6以前舊版本中var宣告不夠嚴謹,同名變量覆蓋與先使用變量後定義變量仍可以輸出undefined而未報錯使除錯困難,所以產生了新的宣告方式let、const。 > ES6以前 var() > ES6以後 let() 與 const() ## 他們是甚麼 :pencil2: ```javascript= // 在JavaScript中宣告變數的方式,就是告訴瀏覽器我們需要一塊儲存空間(記憶體空間),並且在 // 那個空間存放指定數據。 var data = "第一週筆記" 宣告 變量名稱 = 要存的數據 ``` 變量名稱的一些規則 * 命名使用英文大小寫、數字、下划線或是$組成 * 名稱不能用數字當開頭 * 不能使用JS中的關鍵字語保留字 * 嚴格區分大小寫 * 使用駝峰命名 > [關於變量延伸閱讀](https://www.w3school.com.cn/js/js_variables.asp) > [保留字](https://www.w3school.com.cn/js/js_reserved.asp) ## 先了解何謂作用域 作用域決定了這些變量的可訪問性 JavaScript中有兩種作用域 * 全局作用域 * 局部作用域 ### 局部作用域 ```javascript= 1.定義在{}裡面 2.有效範圍只有在定義那行到大括號結束,函式之外的所有程式碼都不能存取這個變數。 3.在局部作用域中的變量稱為局部變量 4.函數function後的{}屬於局部作用域 ``` ### 全局作用域 ```javascript= 1.定義在{}外面 2.有效範圍在定義那行到文末,全局變量在整個程式中都可以被存取與修改。 3.在全局作用域中的變數稱為全局變量 ``` **實例:** ```javascript= // 全局作用域 var a = 1; { // 局部作用域 function myFunction() { // 函數局部作用域 console.log(a); var c = 3; } // 局部作用域 } myFunction(); // a可被函式使用,因此輸出 1 // 因變量定義在函式當中c將會找不到 console.log(c); // 輸出 Uncaught ReferenceError: d is not defined // // 全局作用域 ``` ## 關於 var :pencil2: 在ES6前宣告變量的方式,是**最弱的變數宣告**,其作用域是「函式作用域」,也就是在function 內宣告的 var,要在該 function 才有作用 ,但是如果在函式外宣告的話,其作用範圍則為 全域性。 :point_right: 特性 * 可重複定義同變量名且不會報錯 * 可以重新賦值 * 可先使用後定義(預解析),但是會輸出undefined * 定義在全局作用域時,在整個程式中都可被存取予修改 [預解析](https://iter01.com/561971.html) **實例:** ```javascript= console.log(DemonSlayer); var DemonSlayer; // 此時未賦予任何值且先使用後定義,但是依然可以輸出undefined var DemonSlayer = "炭治郎"; // 使用var可以重新再宣告一次同名變量 console.log(DemonSlayer); // 賦予一個初始化的值,輸出為 炭治郎 DemonSlayer = "伊之助"; console.log(DemonSlayer); // 給變量新的值 伊之助且輸出,可得知var可以重新賦值 ``` ## 關於let :pencil2: 以 let 宣告的變數,其作用域是「局部作用域」,也就是 { } 包住的區域,一但離開 { }範圍,這個變數就不會被存取到。 :point_right: 特性 * 重複定義變量名稱會有錯誤提示 * 先使用後定義會有錯誤提示 * 可以重新賦值 * 基本上用法與var相同 **實例:** ```javascript= // console.log(DemonSlayer); // let DemonSlayer; // let先使用後定義,系統會提示該變量未宣告 // Uncaught ReferenceError: Cannot access 'DemonSlayer' before initialization // 必須先定義 let DemonSlayer; console.log(DemonSlayer); // 未賦值 輸出undefined // let DemonSlayer = "炭治郎"; // 使用let不可以重新再宣告一次同名變量,系統提示該變量已被宣告 // Uncaught SyntaxError: Identifier 'DemonSlayer' has already been declared // 必須直接賦值 DemonSlayer = 炭治郎; // 直接賦予初始化的值 console.log(DemonSlayer); // 輸出為 炭治郎 DemonSlayer = "伊之助"; console.log(DemonSlayer); // 給變量新的值 伊之助且輸出,可得知let也可以重新賦值 ``` ## 關於const :pencil2: const 可以視為 let 的常數加強版,let 有的特性 const 都有,但 const 額外多了常數保護的特性。 在宣告 const 時就必定要指定給值,不然會產生錯誤。而且指定後不能更改賦值。 :point_right: 加強特性 * 先告要先賦值初始化,不然會報錯 * 宣告變量後就無法再修改賦予值 **實例:** ```javascript= const IP = "110.22.XX.127"; // 恆定不動變數IP位址 const exPhone = 0957733822; // 電話號碼 exPhone = 0912345678; // 無法修改變量的值 系統錯誤賦值給常量變量 // Uncaught TypeError: Assignment to constant variable. ``` ## 總結 | | 重複定義 | 重新賦值 | 預解析 | 區分作用域 | | ----- | --------| -------- |---------| ------- | | var | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | 在function時區分 | | let | :x: | :heavy_check_mark: | :x:| :heavy_check_mark: | | const | :x: | :x: | :x: | :heavy_check_mark:| ## 參考資料 [JavaScript 宣告: var、let、const](https://www.iware.com.tw/blog-458.html) [[JS學徒特訓班] JavaScript ES6 : var, let, const 差異](https://codinggirl.timelog.to/a174653905) [w3school JS 變量](https://www.w3school.com.cn/js/js_variables.asp) [w3school JS let](https://www.w3school.com.cn/js/js_let.asp) [w3school JS const](https://www.w3school.com.cn/js/js_const.asp) [函式與作用域](https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part3/function_scope.html)
{"metaMigratedAt":"2023-06-16T12:15:58.911Z","metaMigratedFrom":"Content","title":"var、let、const 的差異?","breaks":true,"contributors":"[{\"id\":\"663fae2d-2bb5-4437-90b7-96f11a50e120\",\"add\":4591,\"del\":1107}]"}
Expand menu