let 命令
let
命令印衔,用來(lái)聲明變量。類似 var
吸申,但是只在 let
命令所在的代碼塊內(nèi)有效。
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
for
循環(huán)還有一個(gè)特別之處享甸,就是設(shè)置循環(huán)變量的那部分是一個(gè)父作用域截碴,而循環(huán)體內(nèi)部是一個(gè)單獨(dú)的子作用域。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
上面代碼輸出3次 abc
蛉威。表明代碼塊內(nèi)容變量 i
與循環(huán)變量 i
不在同一個(gè)作用域日丹,有各自單獨(dú)的作用域。
不存在變量提升
var
命令會(huì)發(fā)生“變量提升”現(xiàn)象蚯嫌,即變量可以在聲明之前使用哲虾,值為 undefined
。
let
改變了語(yǔ)法行為择示,一定先聲明后使用束凑。
暫時(shí)性死區(qū)
只要塊級(jí)作用域內(nèi)存在 let
命令,它所聲明的變量就“綁定”這個(gè)區(qū)域栅盲,不再受到外部影響汪诉。
var tmp = 123;
if (true) {
tmp = 'abc'; //ReferenceError
let tmp;
}
** ES6 明確規(guī)定,如果區(qū)塊內(nèi)存在 let
和 const
命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量形成封閉作用域扒寄。 **
typeof
不在是一個(gè)安全的操作
typeof x; //ReferenceError
let x;
如果一個(gè)變量沒(méi)有被聲明鱼鼓,不會(huì)報(bào)錯(cuò)。
不允許重復(fù)聲明
塊級(jí)作用域
ES6 的 let
為 JavaScript 新增了塊級(jí)作用域该编。
允許塊級(jí)作用域的任意嵌套迄本。
外層作用域無(wú)法讀取內(nèi)層作用域的變量。
內(nèi)層可以定義外層同名的變量课竣。
do 表達(dá)式
塊級(jí)作用域是一個(gè)語(yǔ)句嘉赎,講多個(gè)操作封裝在一起,沒(méi)有返回值于樟。
現(xiàn)在有一個(gè)提案曹阔,使它變?yōu)?do
表達(dá)式。
let x = do {
let t = f();
t * t + 1;
}
上面代碼隔披,變量x會(huì)得到整個(gè)塊級(jí)作用域的返回值。
const命令
const
聲明一個(gè)只讀的常量寂拆。一旦聲明奢米,值不能改變。
本質(zhì)
const
保證的是變量指向的內(nèi)存地址不得改動(dòng)纠永。
當(dāng)?shù)刂分赶蛞粋€(gè)對(duì)象時(shí)鬓长,對(duì)象本身是可變,可以添加新屬性尝江。
如果真的想將對(duì)象凍結(jié)涉波,可以使用 Object.freeze
方法。
const foo = Object.freeze({});
// 常規(guī)模式時(shí)炭序,下面一行不起作用啤覆;
// 嚴(yán)格模式時(shí),改行會(huì)報(bào)錯(cuò)
foo.prop = 123;
除了將對(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] );
}
})
}
ES6聲明變量的六種方法
var
辜纲、function
笨觅、let
、const
耕腾、import
见剩、class
頂層對(duì)象的屬性
ES5時(shí),瀏覽器中的頂層對(duì)象指的是 window
扫俺,Node指的是 global
對(duì)象苍苞。
ES6為了改變這一點(diǎn),var
和 function
命令聲明和ES5保持一致牵舵,let
命令柒啤、const
命令倦挂、class
命令聲明的全局變量,不屬于頂層對(duì)象的屬性担巩。