嗨,這是 JS 系列的第一篇,
我想要先從全域變數與全域屬性談起,那我們就開始吧!
為什麼變數需要宣告?能不宣告直接用嗎?
💡先講結論:
沒有透過「宣告的方式」所產生出來的變數,會是一個「全域的 windows 物件底下的一個屬性」。
變數如果不透過 var、let 、const 宣告的話,會變成一個名為 windwos 物件底下的一個屬性,該屬性是一個全域屬性!
範例:
function fn1(){
// 注意,a 變數並沒有透過 var、let、const 來宣告,
// 卻可以被底下的 fn2() 所使用
a = '小明';
}
function fn2(){
console.log(a);
console.log(windows.a)// 實際上這個 a 變數是 winsows 物件下的一個屬性
}
fn1(); // 呼叫 fn1(),產生一個具全域屬性 a
fn2(); // 呼叫 fn2(),印出兩次小明
這種沒有透過「宣告」的方式所產生出來的變數,會因為是一個全域屬性的關係,容易被汙染,進而難以 debug。
那變數與屬性的差異為何?
💡先講結論:
差異就是只有「屬性」才可以使用 delete 運算子刪除 。
範例
a = '小白'; //因為沒有用宣告字,所以會在 windows 物件底下會新增一個屬性叫做 a
delete a; // a 是一個全域屬性,可透過 delete 刪除
console.log(windows.a); // undefined
console.log(a); // Uncaught ReferenceError: a is not defined
var a = '小白'; // 雖然是用「宣告的方式」,但 windows 物件底下還是會新增一個屬性叫做 a,
// 但透過「宣告的方式」所產生出來的屬性是無法利用 delete 運算子刪除的
delete a; // 無法透過 delete 刪除
console.log(windows.a); //印出小白
console.log(a); // 印出小白
大家對於全域變數和全域屬性,有沒有比較清楚了呢?
最後做個總結:
沒使用宣告字宣告的變數 -> 全域屬性,可用 delete 運算子刪除此屬性。
使用 var 宣告字宣告的變數 -> 全域變數,無法使用 delete 運算子刪除。