一、前提
解決ES5中只有全局作用域和函數(shù)作用域,沒有塊級作用域而帶來的不合理的場景。
let
基本用法
用法和var 一樣,只是let聲明的變量只有在let命令所在的代碼塊有效
{ let a = 10; var b = 1;}a // ReferenceError: a is not defined.b // 1可以看出var 聲明的變量在代碼塊之外也是可以調(diào)用,而let聲明的則調(diào)用報(bào)錯(cuò)。所以let 聲明只在它聲明的當(dāng)前代碼塊中才能調(diào)用。
變量提升
在使用 var 的時(shí)候會(huì)出現(xiàn) “變量提升”的現(xiàn)象,即變量可以在聲明之前使用,值為undefined。let 改變了這種現(xiàn)狀,但是必須先聲明在使用,如果在聲明之前使用則會(huì)出現(xiàn)報(bào)錯(cuò)。如下:
// var 的情況console.log(foo); // 輸出undefinedvar foo = 2;// let 的情況console.log(bar); // 報(bào)錯(cuò)ReferenceErrorlet bar = 2;
暫時(shí)性死區(qū)
只要塊級作用域內(nèi)部存在 let 或者 const 命令,它所聲明的變量就“綁定”在這個(gè)區(qū)域,不會(huì)受外部影響。且暫時(shí)性死區(qū)的本質(zhì)就是,只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。如下:
var tmp = 123;if (true) { tmp = 'abc'; // ReferenceError let tmp;}ES6 明確規(guī)定,如果區(qū)塊中存在 let 和 const 命令,這個(gè)區(qū)塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會(huì)報(bào)錯(cuò)。
總之,在代碼塊內(nèi),使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時(shí)性死區(qū)”(temporal dead zone,簡稱 TDZ)。如下:
if (true) { // TDZ開始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ結(jié)束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123}注意:
++使用let聲明變量時(shí),只要變量在還沒有聲明完成前使用,就會(huì)報(bào)錯(cuò)。上面這行就屬于這個(gè)情況,在變量x的聲明語句還沒有執(zhí)行完成前,就去取x的值,導(dǎo)致報(bào)錯(cuò)”x 未定義“。++
不允許重復(fù)聲明
let 不允許在同一個(gè)作用域內(nèi)聲明同一個(gè)變量,如下:
// 報(bào)錯(cuò)function func() { let a = 10; var a = 1;}// 報(bào)錯(cuò)function func() { let a = 10; let a = 1;}或者如下:
function func(arg) { let arg;}func() // 報(bào)錯(cuò)function func(arg) { { let arg; }}func() // 不報(bào)錯(cuò)塊級作用域
上面也提到過在es5中沒有塊級作用域的概念,只有函數(shù)作用域和全局作用域,那么就帶來了一些問題,如下:
新聞熱點(diǎn)
疑難解答
圖片精選