函式作用域
變量提升,可在宣告前使用,值為undefined
console.log(name); //undefined
var name = 'John';
console.log(name); //John
允許重複宣告,覆蓋前面的值
var a = 'a';
console.log(a); // a
var a = 'b';
console.log(a); // b
區塊作用域 { }
沒有變量提升,一定要宣告使用,否則會報 ReferenceError 錯誤
console.log(name); //報 ReferenceError: name is not defined 錯誤
let name = 'John';
console.log(name); //John
未執行區塊,let變數都不能使用
{
let a = 'a';
console.log(a) //a
}
console.log(a); //ReferenceError: a is not defined
常搭配for迴圈使用
for(let i=0;i<5;i++){
console.log(i); //0 1 2 3 4
}
不允許重複宣告
let a = 'a';
console.log(a); // a
let a = 'b';
// SyntaxError: Identifier 'a' has already been declared
暫時性死區
{
console.log(name); //ReferenceError: Cannot access 'name' before initialization
let name = 'Jay';
}
編譯器解讀
{
let name //暫時性死區 TDZ
console.log(name);
name = 'Jay';
}
let會有hoisting,提升到區塊作用域的上方,但是會出現TDZ,會執行,但不會出現undefined,無法呼叫變數,會出現ReferenceError 錯誤
區塊作用域
沒有變量提升,宣告常數,值不可以更改
console.log(name); //報 ReferenceError: name is not defined 錯誤
const name = 'John';
console.log(name); //John
不允許重複宣告、不允許重新給值、一定要給值
//沒有給值報錯
const a
// SyntaxError: Missing initializer in const declaration
//重複宣告
const a = 'a';
const a = 'b';
//SyntaxError: Identifier 'a' has already been declared
//改變值
const a = 'a';
a = 'b';
// TypeError: Assignment to constant variable.
常數宣告物件或陣列類型,參照類型的值可以改變
const person ={
name: 'John',
money: 500
}
person.name = 'Jay';
console.log(person); //{name: "Jay", money: 500}
Object.freeze(person); //物件凍結,無法新增刪除及調整前屬性值
person.money = 1000;
console.log(person); //{name: "Jay", money: 500}
常用在常量、聲明匿名函數、箭頭函數
名稱 | 變量提升 | 暫時性死區 | 重複宣告 | 初始值 | 作用域 |
------------- | -------------
var | 允許 |不存在 undefined | 允許 | 不需要 | 函式 |
let | 不允許 | 存在 ReferenceError錯誤 | 不允許 | 不需要 | 區塊 |
const | 不允許 | 存在 ReferenceError錯誤 | 不允許 | 不需要 | 區塊 |
for(var i=0; i<3; i++){
console.log(i);// 0 1 2
}
console.log(i); // 3 <- 被覆蓋
在「開發人員工具」輸入window,會發現i被掛載到 window 物件下成為屬性,不可以被刪除。容易在開發中導致很多錯誤,不容易查找,也容易被覆蓋。
hosting -> hoisting ?
另外,使用var並不會意外污染全域變數吧?不宣告變數就使用才會。
用var會污染for迴圈外的變數倒是一個需要注意的...feature XD,有了let這個問題就解決了。
謝謝您的指教,我會在修正文章內容
最後「總結」的部分,表格的第一項中的「名稱」應該是 var
,好像不小心貼成 不存在 undefined
了 XD!
謝謝您的提醒^^