JavaScript
一種被廣泛使用的程式語言,好上手也最容易踩雷,從 ES5進化到 ES6後增加了一些變數宣告方式與不少的語法糖,其歷史沿革已有很多前輩說明,為了方便之後描述,以下 JavaScript簡稱為 JS。
JS 變數宣告
var
在 ES5時期,要宣告一個變數會使用 var作為開頭,但它有個缺點,就是它會建立在全域,在後續開發上會讓造成混淆,像是以下例子:
1 | var a = 1 |
透過瀏覽器(開發者模式)來看,會發現在 window中找得到 a這個變數,這很可能讓後續寫下的變數或者函式抓到同樣的變數(註1),進而造成不必要的錯誤。不過,它不是不能用,根據實際情況改變寫法才是我們要的。
順帶一提,若有安裝 ESLint這類的檢查工具,這個宣告方式還是會被建議改成 let。
註1 : 若函式裏頭未宣告且命名一個變數並賦予值,那麼此變數就會在全域環境中建立一個該變數的名稱(這個行為是 Hoisting,中文名為提升)。
1 | var b = function (){ |
let
在 ES6中,新增了 let與 const,這邊先介紹 let。
特性
- 只在某區塊(例如函式)中有作用
- 無法重複宣告同樣變數名稱
- 變數的值可改變
範例
為了解決 var所帶來的困擾,使用 let來做為變數宣告會是一個比較好的方式,它的作用範圍被限制在某個區塊中,就算不在函式中宣告,在 window中也找不到利用 let所宣告的變數。以下為範例 :
1 | let a = 1 |
const
特性
- 無法重複宣告
- 變數的值不可改變
- 若賦予的值為陣列或物件,可以改變其內部屬性
使用 const宣告的變數為常數,無法改變其值,類似唯讀。
全域環境
上述的範例中會看到 window.a,這其實是物件的寫法,利用 var來宣告變數時,會在 window中新增一個物件屬性,為什麼會提到物件? 因為在說明 let時,自己不禁有個疑問,let a
有宣告,但在全域中卻找不到,那它去哪裡了?
全域之複合環境
這裡似乎有相關的說明。目前自己的理解是,全域環境中是一個複合環境,包含 :
- 物件環境 Object Environment
- 聲明環境 Declarative Environment
範例
以表格來看的話,類似像這樣 :1
2
3
4var a = 10
var b = function(){
console.log(a)
}聲明環境 物件環境 a 10 b funciton()
而 JS是物件導向,以物件來看的話,
1 | // 會在 Global內發現它們 |
瀏覽器中的 Scope
對於瀏覽器來說,當執行環境執行程式碼時,會在瀏覽器的 Scope產生 Global與 Script,而範例的執行環境就是全域環境,所以當變數沒有被告知用哪一種變數宣告,那麼就會根據 JS規則將此變數建立在 Global,若在全域環境下也用 var宣告,那麼就會是建立在 Global。
而使用 let與 const宣告時,它們會被建立在 Script,這就是為什麼無法在 window中找到的原因,因為它們的建立規則不是建立在 Global。