Day.27 「var 成為時代的眼淚!」 —— ES6 區塊作用域 與 提升

之前已經介紹了 var 與函式作用域,今天來更仔細的介紹 ES6 新增的 let 、 const以及與它們相關的區塊作用域
區塊作用域
與函式作用域有點像,一樣都是作用域內沒有的變數可以往外獲取變數,不一樣的是更嚴格謹慎,不只限制在函式上了,連 if else 、 while 、 for 這些循環語句都有限制不能從外往內取,稱為區塊作用域(Block Scope)。
以常見的 var 全域汙染為例:
for (var i = 0; i < 3; i++) {}
console.log(i) // 3,成功在 for 迴圈外面獲取到 for 迴圈內的 i = 3
for (let a = 0; a < 3; a++) {}
console.log(a) // 報錯, a is not definedlet 的特性
let 跟我們常用的 var 用法非常相似,但也是有不同的地方!
-
let不可重複宣告-
使用
var重複宣告不會報錯,只會覆蓋掉var name = '毛毛' var name = '小黃' // 使用 var 重複宣告不會報錯,只會覆蓋掉 -
使用
let重複宣告會報錯let name = "毛毛"; let name = "小黃"; // 使用 let 重複宣告會報錯
-
-
區塊作用域
-
使用
var容易汙染全域作用域for (var i = 0; i < 3; i++) {} console.log(i) // 成功在 for 迴圈外面獲取到 i = 3 -
使用
let則能讓變數限制在區塊內for (let i = 0; i < 3; i++) {} console.log(i) // 報錯, i is not defined
-
-
變數提升效果不同
-
使用
var會自動提升,並顯示未定義undefinedconsole.log(name) // undefined var name = '毛毛' -
使用
let宣告比較嚴謹,會直接報錯(也就是俗稱的死區),讓 debug 效率變高console.log(name) // 報錯 let name = '毛毛'
-
const 的特性
-
必須要賦初始值
const PI; // 報錯 -
常數不能修改
const PI = 3.14159265 PI++ // 報錯 -
一樣也具有區塊作用域
-
對陣列或物件內的屬性做修改,並不會報錯
- 因為我們知道物件型別存的是參考(地址),只要 Stack 值不變就不會報錯
const person = { name: '毛毛', gender: '男' } person.name = '鮭魚' person.age = 27 console.log(person) // { name: "鮭魚", gender: "男", age: 27 }
- 因為我們知道物件型別存的是參考(地址),只要 Stack 值不變就不會報錯
總結
會使用 let 與 const 後,就比較少使用到 var 了,在宣告物件型別或不會主動修改值得變數都會建議使用 const 來宣告!這樣比較不容易變動到變數而出現意想不到的 bug。
Related Posts
Day.30 「什麼!? Promise 的語法糖?」 —— ES8 Async & Await
ES8 新增了 async 與 await 兩個語法,這兩個語法也是為了更方便解決非同步的語法,可以說是 Promise then 的語法糖。
Day.29 「Class 語法糖~」 —— ES6 Class 構造函式
ES6 新增了更接近傳統語言寫法的 Class 這個概念,基本上可以當作是一個**語法糖**,絕大部分的功能在 ES5 都可以做到,但 Class 可以讓構造函式的寫法更加清新!
Day.28 「Promise 初體驗~」 —— ES6 Promise
我們前面已經學習了回調函式(Callback Function)與構造函式(Constrcutor),而 Promise 是 ES6 新增用來解決非同步回調地域的新語法,同時也是一個構造函式!
Johnson Mao
A passionate software engineer and blogger sharing thoughts on technology, AI, and development.