在es6中,可以使用const關(guān)鍵字來(lái)聲明只讀常量,語(yǔ)法“const 常量名 = 常量值;”;一旦聲明,常量必須進(jìn)行初始化且初始化的值就不能改變。const聲明的常量屬于塊作用域,受到“暫存死區(qū)”的約束,不會(huì)在window上創(chuàng)建任何全局屬性,不可重新分配,不可重新聲明。
本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。
在es6中,可以使用const關(guān)鍵字來(lái)聲明只讀常量。
es6 const關(guān)鍵字
const聲明一個(gè)只讀的常量。一旦聲明,常量必須進(jìn)行初始化且初始化的值就不能改變。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
const 常量遵守以下規(guī)則:
-
是屬于塊作用域的。
-
受到“暫存死區(qū)”的約束。
-
它不會(huì)在 window 上創(chuàng)建任何全局屬性。
-
不可重新分配。
-
不可重新聲明。
const一旦聲明變量,就必須立即初始化。
const foo; // SyntaxError: Missing initializer in const declaration
上面代碼表示,對(duì)于const來(lái)說(shuō),只聲明不賦值,就會(huì)報(bào)錯(cuò)。
const的作用域與let命令相同:只在聲明所在的塊級(jí)作用域內(nèi)有效。
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined
const命令聲明的常量也是不提升,同樣存在暫時(shí)性死區(qū),只能在聲明的位置后面使用。
if (true) { console.log(MAX); // ReferenceError const MAX = 5; }
上面代碼在常量MAX聲明之前就調(diào)用,結(jié)果報(bào)錯(cuò)。
const聲明的常量,也與let一樣不可重復(fù)聲明。
var message = "Hello!"; let age = 25; // 以下兩行都會(huì)報(bào)錯(cuò) const message = "Goodbye!"; const age = 30;
const本質(zhì)
const實(shí)際上保證的,并不是變量的值不得改動(dòng),而是變量指向的那個(gè)內(nèi)存地址所保存的數(shù)據(jù)不得改動(dòng)。對(duì)于簡(jiǎn)單類(lèi)型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個(gè)內(nèi)存地址,因此等同于常量。但對(duì)于復(fù)合類(lèi)型的數(shù)據(jù)(主要是對(duì)象和數(shù)組),變量指向的內(nèi)存地址,保存的只是一個(gè)指向?qū)嶋H數(shù)據(jù)的指針,const只能保證這個(gè)指針是固定的(即總是指向另一個(gè)固定的地址),至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了。因此,將一個(gè)對(duì)象聲明為常量必須非常小心。
const foo = {}; // 為 foo 添加一個(gè)屬性,可以成功 foo.prop = 123; foo.prop // 123 // 將 foo 指向另一個(gè)對(duì)象,就會(huì)報(bào)錯(cuò) foo = {}; // TypeError: "foo" is read-only
上面代碼中,常量foo儲(chǔ)存的是一個(gè)地址,這個(gè)地址指向一個(gè)對(duì)象。不可變的只是這個(gè)地址,即不能把foo指向另一個(gè)地址,但對(duì)象本身是可變的,所以依然可以為其添加新屬性。
下面是另一個(gè)例子。
const a = []; a.push('Hello'); // 可執(zhí)行 a.length = 0; // 可執(zhí)行 a = ['Dave']; // 報(bào)錯(cuò)
上面代碼中,常量a是一個(gè)數(shù)組,這個(gè)數(shù)組本身是可寫(xiě)的,但是如果將另一個(gè)數(shù)組賦值給a,就會(huì)報(bào)錯(cuò)。
如果真的想將對(duì)象凍結(jié),應(yīng)該使用Object.freeze方法。
const foo = Object.freeze({}); // 常規(guī)模式時(shí),下面一行不起作用; // 嚴(yán)格模式時(shí),該行會(huì)報(bào)錯(cuò) foo.prop = 123;
上面代碼中,常量foo指向一個(gè)凍結(jié)的對(duì)象,所以添加新屬性不起作用,嚴(yán)格模式時(shí)還會(huì)報(bào)錯(cuò)。
除了將對(duì)象本身凍結(jié),對(duì)象的屬性也應(yīng)該凍結(jié)。下面是一個(gè)將對(duì)象徹底凍結(jié)的函數(shù)。
var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, i) => { if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); } }); };
【