var、let、const與JavaScript變數/常量的定義
早期的JavaScript中,宣告變數只能使用var
關鍵字定義變數,並沒有定義常量的功能。通過var
關鍵字定義的變數,其作用域只能函式級或是全域性作用域,並沒有塊級作用域。ES6(ECMAScript 2015)對這一問題做了改善,增加了用於定義塊級變數的let
關鍵字和用於定義常量的const
關鍵字。
1. var
定義變數
1.1 語法及說明
var
關鍵字用於宣告一個或多個變數,宣告多個變數時使用逗號(,
語法法結構如下:
var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];
varname1…varnameN
- 變更名。可以是任何合法的識別符號。value1…valueN
- 初始化值。可選。可以是任何合法的表示式。
使用var
宣告變數時,宣告的變數作用域是在當前位置的上下檔案中:函式的內部(宣告在函式內)或者全域性(宣告在函式外)。
1.2 使用及特點
使用var
定義的變數有以下特點:
變數宣告提升
無論在程式碼的任何位置宣告變數,執行引擎都會在任何程式碼執行之前處理。由於這個原因,所以在程式碼中的任意位置宣告變數與在程式碼開頭宣告變數是等效的。
這意味著我們可以在定義變數之前使用,這個行為叫做'hoisting'
,也就是把所有的變數宣告移動到函式或者全域性程式碼的開頭位置。
hoist = 'http://itbilu.com'; var hoist; // 可以理解為: var hoist; hoist = 'http://itbilu.com';
注意:雖然變數宣告提升讓我們可以先使用再定義變數,但建議總是先定義再使用變數,這樣可以讓變數的作用域更加清晰。
宣告與未聲名變數的區別
未宣告的變數會被新增一個全域性作用域,而宣告變數作用域是當前上下文:
function x() { y = 1; // 在嚴格模式下會丟擲ReferenceError var z = 2; } x(); console.log(y); // '1' console.log(z); // ReferenceError: z is not defined
宣告變數在任何程式碼執行前建立,而未宣告的變數只有在執行賦值操作的時候才會被建立:
console.log(a); // 丟擲ReferenceError。 console.log('still going...'); // 不會執行
var a; console.log(a); // "undefined"或""(不同執行引擎的實現不同) console.log('still going...'); // 'still going...'
宣告變數是不可配置屬性,而未宣告變數是可配置的:
var a = 1; b = 2; delete this.a; // 在嚴格模式下丟擲TypeError,非嚴格模式下執行失敗且無任何提示 delete this.b; console.log(a, b); // 丟擲ReferenceError,'b'屬性已經被刪除
以上三點是宣告與未宣告變數區別,但錯誤表現是不可預知的。而在嚴格模型下,使用未賦值的變數會丟擲異常,推薦總是先定義(宣告)再使用變數。
全域性作用域與函式作用域
函式內部宣告的變數只能在函式內部使用,函式外部宣告的變數可以全域性使用:
var x = 0; function f(){ var x = 1, y = 1; } f(); console.log(x); // 0 console.log(y); // ReferenceError: y is not defined
2. let
定義塊級變數
2.1 語法及說明
let
用於定義塊級變數,其語法結構類似於var
:
let varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];
var
宣告的變數是函式級的或者是全域性的,而let
用於宣告塊級作用域。
如,使用let
宣告一個塊級變數:
if (x > y) { let gamma = 12.7 + y; i = gamma * x; }
2.2 與var
的異同
let
與var
的區別主要體現在作用域上,當在子程式碼塊中使用中其宣告的是塊級變數,而var
宣告的是全域性變數:
var a = 5; var b = 10; if (a === 5) { let a = 4; // if 塊級作用域 var b = 1; // 函式級作用域 console.log(a); // 4 console.log(b); // 1 } console.log(a); // 5 console.log(b); // 1
在函式或程式頂層使用時,let
與var
沒有什麼區別:
var x = 'global'; let y = 'global'; console.log(this.x); // 'global' console.log(this.y); // 'global'
3. const
定義常量
const
用於宣告一個或多個常量,宣告時必須進行初始化,且初始化後值不可再修改:
const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];
const
定義常量與使用let
定義變數十分相似:
- 二者都是塊級作用域
- 都不能和它所在作用域內的其他變數或函式擁有相同的名稱
兩者還有以下兩點區別:
const
宣告的常量必須初始化,而let
宣告的變數不用- 常量的值不能通過再賦值改變,也不能再次宣告。而變數值可以修改
參考連結: