Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

var, let, const 變數宣告差別

Imgur

ES6 提出的 let 與 const,能讓宣告變數的使用方式、型態可以更謹慎,也會限制 scope 範圍,一起來看看 var, let, const 之間有什麼差異吧!

var, let, const 的差異

可以被修改 可重複宣告 作用域 hoisting(變量提升) 宣告前存取
var ✔️ 可以 ✔️ 可重複宣告並覆蓋 僅限 funciton 有 hoisting undefine
let ✔️ 可以 ❌ 不可 block 區塊 有 hoisting + TDZ ReferenceError
const ❌ 不可 ❌ 不可 block 區塊 有 hoisting + TDZ ReferenceError

var

var 的作用域只有在函式區塊,在 if 或 for 迴圈是沒有作用域的,都會被當成全域使用,如有外部程式跟這些變數名稱相同時,容易發生不可預期的錯誤,或在無意間修改了不想修改的變數

在 var 宣告中會被拆成兩行,變數的宣告會提升,賦值不會提升

1
2
console.log(a); //undefine
var a = 1;

等同於

1
2
3
var a;
console.log(a);
a = 1;

再來看看 var 的作用域

function

1
2
3
4
5
6
7
var a = 1;
function print() {
var a = 2;
console.log(a);
}
print(); // 2
console.log(a); // 1

在函式中是有作用域的,函式外的 a 不會被覆蓋掉

if

1
2
3
4
5
6
var a = 1;
if (true) {
var a = 2;
console.log(a); //2
}
console.log(a); //2 a被覆蓋掉了

for

1
2
3
4
5
6
7
var a = 5;
for (var a = 1; a < 10; a++) {
var b = 10;
console.log(a); // 1 2 3 4 5 6 7 8 9
}
console.log("a", a); // 10
console.log("b", b); // 10

在 if 跟 for 裡的變數都會被修改,b 在 global 未宣告,卻可以印出數值,證明在這邊是沒有自己的區塊的

如將此改為 let,就可以達到我們要的結果

1
2
3
4
5
6
7
var a = 5;
for (let a = 1; a < 10; a++) {
let b = 10;
console.log(a); // 1 2 3 4 5 6 7 8 9
}
console.log("a", a); // 5
console.log("b", b); // b is not defined

迴圈+非同步

預期: 印出每秒 1-9 的數字

1
2
3
4
5
for (var a = 1; a < 10; a++) {
setTimeout(function () {
console.log(a); // 10(印了9次)
}, a * 1000);
}

印出來的是 10,並非我們想要的結果,可以用閉包的方式解決

1
2
3
4
5
6
7
for (var a = 1; a < 10; a++) {
(function (b) {
setTimeout(function () {
console.log(b); // 1 2 3 4 5 6 7 8 9
}, b * 1000);
})(a);
}

如此一來可以出現我們要的結果,但最簡單的方式還是直接改為 let 就可以輕易的做到

1
2
3
4
5
for (let a = 1; a < 10; a++) {
setTimeout(function () {
console.log(a); // 1 2 3 4 5 6 7 8 9
}, a * 1000);
}

let & const

let、const 的作用域都在 block{}區塊,他們兩者最大的不同是
let 可以被修改的變數
const 不可以被修改的常數,除非是參考值(物件、陣列)

比較特別的是,let、const 有「暫時死區」(Temporal Dead Zone,TDZ)的特性,中文解釋為「時間上暫時無法達到的區域」,如果在宣告變數之前使用變數,這個變數就是存在「暫時死區」中無法存取,可以幫助我們養成在變數還沒宣告之前,不要使用他的好習慣,讓程式碼可讀性提高。
那 let、const 會不會有 hoisting 呢?
答案是: 有的! let、const 存在變數提升,但是在「提升之後」以及「賦值之前」的 TDZ 之間是不存在的。

物件是參考

1
2
3
4
5
6
7
8
const a = [1, 2, 3, 4, 5];
console.log(a);
a[5] = 6;
console.log(a);
const person = {
name: "John",
};
console.log(person);

const 如果為參考值(by reference)是可以被修改的


ES6 提出的 let 與 const,能讓宣告變數可以更謹慎,也會限制範圍,才不會造成出乎意料的結果。


以上是我的學習筆記,希望也有幫助到你哦 😀



Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️