本質
const
實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。
對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同於常量。
但對於復合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const
只能保證這個指針是固定的(即總是指向另一個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。
基本用法
-
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
const
聲明一個只讀的常量。一旦聲明,常量的值就不能改變。 -
const foo; // SyntaxError: Missing initializer in const declaration
上面代碼表示,對於
const
來說,只聲明不賦值,就會報錯。 -
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined
const
的作用域與let
命令相同:只在聲明所在的塊級作用域內有效。 -
if (true) { console.log(MAX); // ReferenceError const MAX = 5; }
const
命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。 -
var message = "Hello!"; let age = 25; // 以下兩行都會報錯 const message = "Goodbye!"; const age = 30;
不可重復聲明
復合類型的數據
-
const foo = {}; // 為 foo 添加一個屬性,可以成功 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個對象,就會報錯 foo = {}; // TypeError: "foo" is read-only
上面代碼中,常量
foo
儲存的是一個地址,這個地址指向一個對象。不可變的只是這個地址,即不能把foo
指向另一個地址,但對象本身是可變的,所以依然可以為其添加新屬性。 -
const a = []; a.push('Hello'); // 可執行 a.length = 0; // 可執行 a = ['Dave']; // 報錯
上面代碼中,常量
a
是一個數組,這個數組本身是可寫的,但是如果將另一個數組賦值給a
,就會報錯。