JavaScript 變數 Variables var let const
定義
變數是用來儲存值的一個容器。
舉個例子,用 JavaScript 來表示蘋果價格為 25 元
1 | var applePrice = 25 |
變數的命名規則
- 變數必須是唯一的名稱。
例如 applePrice 代表的是蘋果價格,它就不會同時是是香蕉價格或鳳梨價格。
- 可以很簡短。
例如 x 或 y
;或是很具體的描述。例如 applePrice
- 開頭第一個字必須是大小寫字母(letter)、底線(_)、錢符號($),其餘可以包含大小寫字母、數字(0-9)、底線、錢符號。
例如 isOpen 或 $price 與 _pchome24H
- 區分大小寫(case sensitive)。
例如 A 和 a 是不同的變數
- 保留字不能當作變數名稱,
例如 null 或 const
變數宣告
在 JavaScript 中有三種宣告的方式:
var
宣告可改變值的變數,作用域在function(){}內
,如果不在任何function(){}內
宣告 var 變數,這個變數就會變成全域物件的屬性,或稱全域變數。let
宣告可改變值的區域變數,或稱區塊變數,作用域在{}內
。const
宣告不可以改變值的常數,因為不可以改變值,所以宣告的時候就必須賦值。
var/let/const 的差異
重複宣告
var 可以重複宣告,let / const 不可以重複宣告
1 | // 重複宣告 var 變數,可以正常運行 |
先宣告後賦值
可以先宣告 var / let 變數之後才賦值。但 const 宣告的時候必須同時賦值,否則會出錯。
1 | var a; |
重新賦值
var / let 可以重新賦值,const 不可以重新賦值
1 | // 宣告 let 變數 a = 0 |
作用域
var 在 function內
,let / const 在{}內
關於變數的作用域,我有另外寫一篇文章:JavaScript 變數作用域 Variable Scope
1 | // 在 block 內宣告變數,在 block 外取值 |
window 物件
如果在最外層宣告變數,var 變數可以在 window 這個物件裡找到,let / const 變數不會在 window 裡找到。
1 | var a1 = 0 |
額外的議題討論
剛接觸 JavaScript 的時候,最不習慣的地方是變數宣告的地方,因為以前用 C# ,必須在宣告變數的時候也指定好型別,要讓 C# 知道「這是一個正整數的變數」。
1 | int a = 0; |
而 JavaScript 是一個弱型別的程式語言,做變數宣告的時候並不需要先定義變數的型別,只需要讓 JavaScript 知道「這是一個變數」即可。
1 | var a = 0 |
JavaScript 還有一個神奇的地方,居然沒有宣告變數也可以用!
1 | a = 1 |
JavaScript 真的可以不用宣告變數?
在其它程式語言裡,使用未經過宣告的變數是會出錯的,但是在 JavaScript 卻不是這樣。
以瀏覽器來說,不會出錯的原因在於:這樣的操作是發生在 window 這個物件裡。
所以並不是「使用未經宣告的變數」不會出錯,而是這樣的操作對 JavaScript 來說,是在 window 物件裡添加了一個屬性並使用它。
以為是「使用未宣告的變數」,其實是使用了一個全域物件的屬性(或稱全域變數)。
全域汙染的問題
舉個例子,在不知道 init.js 及 main.js 的內容的情況下,要怎麼知道 a 是從哪裡開始產生的?要怎麼知道 a 是在哪裡被改變了?萬一又有其他的地方需要用到 a ,而 a 這個值不正確該怎麼辦?這個 a 已經造成全域汙染的問題了!
透過這個範例可以知道,在不同的地方用了全域變數,會產生全域汙染的問題。
1 | <script src="init.js"></script> |
1 | // init.js |
通常為了避免全域汙染,建議使用宣告變數的方式,把變數的範圍侷限住,以免產生一連串的問題。
1 | <script src="init.js"></script> |
1 | // init.js |
全域變數有宣告跟沒宣告差別在哪?
對 window 物件來說 a 是 window 物件裡的屬性,a 可以用 delete 指令刪除
而 b 雖然也是 window 物件裡的屬性,但它同時是經過宣告的變數,會被當作全域物件裡無法配置(non-configurable)的屬性,所以無法用 delete 來刪除。
1 | a = 0 |