摘要:和都能夠聲明塊級(jí)作用域,用法和是類(lèi)似的,的特點(diǎn)是不會(huì)變量提升,而是被鎖在當(dāng)前塊中。聲明常量,一旦聲明,不可更改,而且常量必須初始化賦值。臨時(shí)死區(qū)臨時(shí)死區(qū)的意思是在當(dāng)前作用域的塊內(nèi),在聲明變量前的區(qū)域叫做臨時(shí)死區(qū)。
主要知識(shí)點(diǎn)有:var變量提升、let聲明、const聲明、let和const的比較、塊級(jí)綁定的應(yīng)用場(chǎng)景
《深入理解ES6》筆記 目錄
varJavaScript中,我們通常說(shuō)的作用域是函數(shù)作用域,使用var聲明的變量,無(wú)論是在代碼的哪個(gè)地方聲明的,都會(huì)提升到當(dāng)前作用域的最頂部,這種行為叫做變量提升(Hoisting)
function test() { var a //a聲明沒(méi)有賦值 console.log("1: ", a) //undefined if (false) { a = 1 } //a聲明沒(méi)有賦值 console.log("3: ", a) //undefined }
test()
如果a沒(méi)有聲明,那么就會(huì)報(bào)錯(cuò),沒(méi)有聲明和聲明后沒(méi)有賦值是不一樣的,這點(diǎn)一定要區(qū)分開(kāi),有助于我們找bug。
//b提升到函數(shù)a頂部,但不會(huì)提升到函數(shù)test。 function test() { function a() { if (false) { var b = 2 } } console.log("b: ", b) } test() //b is not definedlet
let和const都能夠聲明塊級(jí)作用域,用法和var是類(lèi)似的,let的特點(diǎn)是不會(huì)變量提升,而是被鎖在當(dāng)前塊中。
function test() { if(true) { console.log(a)//TDZ,俗稱臨時(shí)死區(qū),用來(lái)描述變量不提升的現(xiàn)象 let a = 1 } } test() // a is not defined function test() { if(true) { let a = 1 } console.log(a) } test() // a is not defined
唯一正確的使用方法:先聲明,再訪問(wèn)。
function test() { if(true) { let a = 1 console.log(a) } } test() // 1const
聲明常量,一旦聲明,不可更改,而且常量必須初始化賦值。
const type = "ACTION"
重新賦值會(huì)報(bào)錯(cuò)
const type = "ACTION" type = 1 console.log(type) //"type" is read-only const type = "ACTION" let type = 1 console.log(type) //Duplicate declaration "type"
const雖然是常量,不允許修改默認(rèn)賦值,但如果定義的是對(duì)象Object,那么可以修改對(duì)象內(nèi)部的屬性值。
const type = { a: 1 } type.a = 2 //沒(méi)有直接修改type的值,而是修改type.a的屬性值,這是允許的。 console.log(type) // {a: 2}
const聲明不允許修改綁定,但允許修改綁定的值
const和let的異同點(diǎn):
相同點(diǎn):const和let都是在當(dāng)前塊內(nèi)有效,執(zhí)行到塊外會(huì)被銷(xiāo)毀,也不存在變量提升(TDZ),不能重復(fù)聲明。
不同點(diǎn):const不能再賦值,let聲明的變量可以重復(fù)賦值。
臨時(shí)死區(qū)(TDZ)臨時(shí)死區(qū)的意思是在當(dāng)前作用域的塊內(nèi),在聲明變量前的區(qū)域叫做臨時(shí)死區(qū)。
if (true) { //這塊區(qū)域是TDZ,訪問(wèn)a會(huì)報(bào)錯(cuò) let a = 1 }
訪問(wèn)TDZ中的變量會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤
但下面這種不會(huì)報(bào)錯(cuò)
console.log(typeof a) //undefined,因?yàn)榇藭r(shí)a不在TDZ中 if (true) { //這塊區(qū)域是TDZ,訪問(wèn)a會(huì)報(bào)錯(cuò) let a = 1 }塊級(jí)作用域的使用場(chǎng)景
除了上面提到的常用聲明方式,我們還可以在循環(huán)中使用,最出名的一道面試題:循環(huán)中定時(shí)器閉包的考題
在for循環(huán)中使用var聲明的循環(huán)變量,會(huì)跳出循環(huán)體污染當(dāng)前的函數(shù)。
for(var i = 0; i < 5; i++) { setTimeout(() => { console.log(i) //5, 5, 5, 5, 5 }, 0) } console.log(i) //5 i跳出循環(huán)體污染外部函數(shù) //將var改成let之后 for(let i = 0; i < 5; i++) { setTimeout(() => { console.log(i) // 0,1,2,3,4 }, 0) } console.log(i)//i is not defined i無(wú)法污染外部函數(shù)
循環(huán)內(nèi)const聲明
在普通的for循環(huán)中使用const變量,由于const變量不可修改,因此會(huì)報(bào)錯(cuò)。而在for-in或者for-of循環(huán)中可以使用const變量。
因?yàn)檠h(huán)為每次迭代創(chuàng)建了一個(gè)新的變量綁定,而不是試圖去修改已綁定的變量的值
let arr = [1,2,3,4]; for(const item of arr){ console.log(item); //輸出1,2,3,4 }全局塊作用域綁定
用var作用域全局作用域時(shí)聲明的全局變量會(huì)覆蓋一個(gè)已經(jīng)存在的全局屬性:
var reg = "hello"; console.log(window.reg) //"hello"
而如果在全局作用域使用let或者const聲明,當(dāng)聲明的變量本身就是全局屬性,比如closed。會(huì)創(chuàng)建一個(gè)新的綁定,但不會(huì)添加全局屬性;就是說(shuō),用let或const不能覆蓋全局變量,只能遮蔽它;
window.closed = false let closed = true closed // true window.closed // false最佳實(shí)踐
在實(shí)際開(kāi)發(fā)中,我們選擇使用var、let還是const,取決于我們的變量是不是需要更新,通常我們希望變量保證不被惡意修改,而使用大量的const,聲明一個(gè)對(duì)象的時(shí)候,也推薦使用const,當(dāng)你需要修改聲明的變量值時(shí),使用let,var能用的場(chǎng)景都可以使用let替代。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/96866.html
摘要:聲明聲明的語(yǔ)法與的語(yǔ)法一致??偨Y(jié)文章都是以深入理解讀書(shū)筆記形式,大部分引用書(shū)中的定義,加上作者的理解,樣例也做了調(diào)整,所有樣例都可以放到里運(yùn)行親自嘗試。 1.變量提升 使用 var 關(guān)鍵字聲明的變量,無(wú)論其實(shí)際聲明位置在何處,都會(huì)被視為聲明于所在函數(shù)的 頂部(如果聲明不在任意函數(shù)內(nèi),則視為在全局作用域的頂部)。這句話從字面上不難理解。 但是他是怎樣一個(gè)過(guò)程,為什么會(huì)這樣。當(dāng)你代...
摘要:沒(méi)有聲明的情況和都能夠聲明塊級(jí)作用域,用法和是類(lèi)似的,的特點(diǎn)是不會(huì)變量提升,而是被鎖在當(dāng)前塊中。聲明常量,一旦聲明,不可更改,而且常量必須初始化賦值。臨時(shí)死區(qū)的意思是在當(dāng)前作用域的塊內(nèi),在聲明變量前的區(qū)域叫做臨時(shí)死區(qū)。 本章涉及3個(gè)知識(shí)點(diǎn),var、let、const,現(xiàn)在讓我們了解3個(gè)關(guān)鍵字的特性和使用方法。 var JavaScript中,我們通常說(shuō)的作用域是函數(shù)作用域,使用var聲...
摘要:錯(cuò)誤的寫(xiě)法錯(cuò)誤的寫(xiě)法中的構(gòu)造函數(shù)新增了支持默認(rèn)參數(shù)和不定參數(shù)。箭頭函數(shù)的簡(jiǎn)單理解箭頭函數(shù)的左邊表示輸入的參數(shù),右邊表示輸出的結(jié)果。但是有了尾調(diào)用優(yōu)化之后,遞歸函數(shù)的性能有了提升。 作為前端切圖仔,越發(fā)覺(jué)得自己離不開(kāi)函數(shù)了。 說(shuō)到JavaScript函數(shù),腦子里都是匿名函數(shù)、普通函數(shù)、閉包函數(shù)、構(gòu)造函數(shù)......然后還能說(shuō)出一大堆函數(shù)的概念。如果你達(dá)到這個(gè)水平,那么函數(shù)對(duì)你來(lái)說(shuō)沒(méi)有難度...
閱讀 2835·2021-11-19 09:40
閱讀 5692·2021-09-27 14:10
閱讀 2168·2021-09-04 16:45
閱讀 1569·2021-07-25 21:37
閱讀 3057·2019-08-30 10:57
閱讀 3058·2019-08-28 17:59
閱讀 1115·2019-08-26 13:46
閱讀 1475·2019-08-26 13:27