JavaScript => var vs let

ck100pro
ck100pro
Published in
4 min readFeb 12, 2020

在說到var和let的差別時,我們要先知道在JavaScript裡面變數的有效範圍(Scope),我們先看下面這個例子,輸出結果大家應該都知道吧~~

輸出結果~~

明明我是先呼叫doing()這個function,而這個function內重新定義了x這個變數,為什麼我後面在呼叫x這個變數的時候,不是顯示doing()這個function裡面定義的x內容。

這是因為變數有效範圍的最小單位是"function",而這個有效範圍我們稱它為『Scope』所以在上面的例子裡雖然有2個x但這2個x其實是不一樣的變數,只不過他們同名而已。

而JavaScript還有另一個特性,那就是當他在function內部找不到所需要的變數他會一直往外去找,直到找到或找不到為止,我們可以改上述的例子來看這情況。

由於doing()這個function裡面沒有x這個變數,所以他會往外找x這個變數。

我們知道var是用來宣告變數的,那我們如果不加var而直接定義x會發生什麼事呢??

下面這個例子,輸出會是什麼呢??

從以下結果可以看出外面的x變數內容被被改寫了!!

前面我們有說到『切分變數有效範圍的最小單位是function』,但這個前提是你是用var去宣告這個變數。

以這個例子來說,由於沒有在doing()這個function裡面重新宣告x變數,導致doing()這個function內的x跑去外面變更了外層的同名變數x。

再來要在說到var的另一個特性,我們把上面的例子改一下,把var加回去並把console.log(x)拉到宣告變數的上面,我們來看輸出結果會是什麼!!

doing()這個function裡面的console.log(x)輸出的結果居然是undefined!!

其實上面這個例子裡,在瀏覽器(或者是編譯器裡)的解讀是以下這個樣子,有看出差異嘛!!

當我們在還沒宣告變數之前就把變數拿來用的時候,JavaScript會在自己的Scope找變數x,當他找到變數x的時候,JavaScript就會把『宣告的語法』拉到這個Scope的最上面,就像上面的例子一樣,而這個特性就是就是JavaScript裡面說的『變數提昇』!!!

『所以,有可能用到的變數盡量都在Scope的最上面先宣告再使用』

由於JavaScript有『變數提昇』,所以在ES6裡面我們可以用『let/const』來取代var,而『let/const』有名為暫時性死區的特性(TDZ)。

而var和let/const最大的區別有以下2個特點。

1: 
let/const是區塊的作用域,也就是由大括號{ }來區隔,而var是以function來做區隔。
2:
在let/const宣告之前就存取的變數或常數,會拋出ReferenceError這個錯誤,而在var宣告 之前就存取對應的變數,則只會有undefined

如下面這例子,可以看到結果會不相同。

用let來宣告變數
用var來宣告變數

--

--