JavaScript塊級(jí)作用域綁定以及狀態(tài)提升詳解
前言
在ES6之前,JavaScript只有經(jīng)典的var聲明,這給開發(fā)者帶來了很多的困擾。在ES6出現(xiàn)后,又增加了let和const關(guān)鍵字的聲明方式。這里會(huì)講有關(guān)變量聲明,作用域,狀態(tài)提升相關(guān)知識(shí)。
作用域/執(zhí)行上下文
在JavaScript的世界里,作用域可以分為三種,分別是全局作用域,函數(shù)作用域,塊級(jí)作用域。
- 全局作用域/執(zhí)行上下文:默認(rèn)或者是最基礎(chǔ)的作用域。一個(gè)程序只有一個(gè)全局作用域,在JavaScript腳本存在的生命周期中都在執(zhí)行堆棧的底部不會(huì)被彈出銷毀。全局作用域中有一個(gè)全局對(duì)象(以瀏覽器環(huán)境為例,這個(gè)全局對(duì)象是window)。
- 函數(shù)作用域:一個(gè)函數(shù)體內(nèi)部是一個(gè)作用域。
- 塊級(jí)作用域:存在于塊中——字符 { 和 } 之間的區(qū)域。(顯然函數(shù)體也是由大括號(hào)包裹的,所以函數(shù)作用域也是塊級(jí)作用域)
var 聲明
var聲明在全局作用域中,會(huì)被添加到全局對(duì)象上成為全局對(duì)象的屬性。在函數(shù)作用域中則會(huì)被提升到函數(shù)頂部。而且不管實(shí)際是否會(huì)執(zhí)行,都會(huì)在預(yù)編譯階段將函數(shù)聲明提升,初始化操作則留在本地。
- var聲明的變量會(huì)被提升到當(dāng)前作用域頂部(當(dāng)前作用域只包括全局作用域或函數(shù)作用域,沒有塊級(jí)作用域)。
塊級(jí)聲明
臨時(shí)死區(qū)(Temporal Dead Zone,TDZ):用來描述 let 和 const 的不提升效果的術(shù)語。JavaScript引擎在掃描代碼發(fā)現(xiàn)變量聲明時(shí),要么將他們提升到作用域頂部(var聲明),要么將聲明放到TDZ(let聲明和const聲明)。訪問在TDZ中的變量會(huì)觸發(fā)運(yùn)行時(shí)錯(cuò)誤,只有執(zhí)行過變量聲明語句后,變量才會(huì)從TDZ中移出,然后才可以正常訪問。
const 和 let 是塊級(jí)標(biāo)識(shí)符,所以聲明的變量、常量也只在當(dāng)前代碼塊中有效,一旦執(zhí)行到塊外就會(huì)立即被銷毀。
- let聲明:可以將變量作用域限制在當(dāng)前代碼塊中。在聲明語句前會(huì)將變量放在臨時(shí)死區(qū)。
- const聲明:用來聲明常量,并且每個(gè)被被const聲明的常量必須進(jìn)行初始化。如果是對(duì)象,則對(duì)象中的值可以修改(cosnt聲明不允許修改綁定,但可以修改綁定的值)
不聲明的變量
在JavaScript中,定義一個(gè)變量不使用關(guān)鍵字聲明也不會(huì)報(bào)錯(cuò)。但不建議這么做。
不管在全局,函數(shù)還是塊作用域里,a = 0 這樣的語句都會(huì)在 window 對(duì)象上創(chuàng)建 a 屬性,實(shí)際上也就是執(zhí)行了 window.a = 0 。而只有在全局作用域中,var a = 0才會(huì)在 window 上創(chuàng)建屬性 a,即為 window.a = 0。
1. 不使用關(guān)鍵字聲明變量
function func() {
b = 0
console.log(b);
console.log(b === window.b);
}
func()
console.log(b === window.b);
// 輸出結(jié)果
/*
0
true
true
*/???? 這部分代碼執(zhí)行過 func 函數(shù),將變量 b 作為 window 對(duì)象的屬性。
2. 使用 var 聲明的變量
function func(x) {
var b = 0
console.log(b);
console.log(b === window.b);
}
func(1)
console.log(b === window.b);
// 輸出結(jié)果
/*
0
false
Uncaught ReferenceError: b is not defined
*/???? 這段代碼就是正常的 var 聲明的變量在函數(shù)作用域內(nèi)提升。
var 聲明和塊級(jí)聲明的區(qū)別
全局作用域綁定
- var聲明在全局作用域中時(shí),會(huì)創(chuàng)建一個(gè)新的全局變量作為全局對(duì)象的屬性(在瀏覽器中為window對(duì)象)。這意味著用 var 可能會(huì)無意中覆蓋一個(gè)已經(jīng)存在的全局變量。
- 塊級(jí)聲明(let 或 const)會(huì)在全局作用域創(chuàng)建一個(gè)新的綁定,但該綁定不會(huì)添加為全局對(duì)象的屬性。所以用塊級(jí)聲明不會(huì)覆蓋全局變量,只能遮蔽它。
let RegExp = 'Hello!' console.log(RegExp); console.log(window.RegExp === RegExp); // 結(jié)果 /* Hello! false */ 復(fù)制代碼
狀態(tài)提升
- var 聲明的變量會(huì)提升到當(dāng)前作用域頂部,在實(shí)例化之前為 undefined。var聲明的變量限制范圍為全局作用域或函數(shù)作用域。
- 塊級(jí)聲明的變量會(huì)被存放到臨時(shí)死區(qū),在實(shí)例化前訪問會(huì)報(bào)錯(cuò) Uncaught ReferenceError
console.log(RegExp); let RegExp = 'Hello!' // Uncaught ReferenceError: Cannot access 'RegExp' before initialization
塊級(jí)綁定的最佳實(shí)踐
默認(rèn)使用 const,只有確實(shí)需要改變變量的值時(shí)使用 let。
函數(shù)聲明提升
函數(shù)提升優(yōu)先級(jí)高于變量提升。
函數(shù)聲明的特點(diǎn):函數(shù)聲明會(huì)被提升到當(dāng)前作用域頂部,并且可以在當(dāng)前作用域內(nèi)部任何地方都可以訪問到。
總結(jié)
到此這篇關(guān)于JavaScript塊級(jí)作用域綁定以及狀態(tài)提升的文章就介紹到這了,更多相關(guān)JS塊級(jí)作用域綁定/狀態(tài)提升內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js跨域問題淺析及解決方法優(yōu)缺點(diǎn)對(duì)比
所謂js跨域問題,是指在一個(gè)域下的頁面中通過js訪問另一個(gè)不同域下 的數(shù)據(jù)對(duì)象,出于安全性考 慮,幾乎所有瀏覽器都不允許這種跨域訪問,這就導(dǎo)致在一些ajax應(yīng)用中,使用跨域的web service會(huì)成為一個(gè)問題。 要解決跨域的問題,就是本文我們需要探討的了2014-11-11
javascript下漢字和Unicode編碼互轉(zhuǎn)代碼
這個(gè)是就是把漢字和Unicode編碼互轉(zhuǎn)的javascript代碼,也是從網(wǎng)上找到了,也許有人用得著!!2010-10-10
JS使用單鏈表統(tǒng)計(jì)英語單詞出現(xiàn)次數(shù)
這篇文章主要為大家詳細(xì)介紹了JS使用單鏈表統(tǒng)計(jì)英語單詞出現(xiàn)次數(shù)的相關(guān)資料,列出所有單詞及其出現(xiàn)次數(shù),感興趣的小伙伴們可以參考一下2016-06-06
js實(shí)現(xiàn)瀏覽本地文件并顯示擴(kuò)展名的方法
這篇文章主要介紹了js實(shí)現(xiàn)瀏覽本地文件并顯示擴(kuò)展名的方法,涉及javascript文件上傳及字符串操作的相關(guān)技巧,非常簡單實(shí)用,需要的朋友可以參考下2015-08-08
javascript入門之window對(duì)象【新手必看】
本文系統(tǒng)介紹了javascript的window對(duì)象以及一些控制函數(shù)的用法,僅供大家參考2016-11-11
按下回車鍵指向下一個(gè)位置的一個(gè)函數(shù)代碼
本篇文章主要是對(duì)按下回車鍵指向下一個(gè)位置的一個(gè)函數(shù)代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-03-03
使用Auto.js?調(diào)用系統(tǒng)短信、電話模塊實(shí)現(xiàn)功能
這篇文章主要介紹了如何使用Auto.js調(diào)用系統(tǒng)短信與電話模塊,并實(shí)現(xiàn)讀取短信與聯(lián)系人的功能,并給出了實(shí)現(xiàn)相應(yīng)功能的代碼2023-03-03
JavaScript ES6常用基礎(chǔ)知識(shí)總結(jié)
ES6中為我們提供了很多好用的新特性,其中包括let,箭頭函數(shù)以及擴(kuò)展運(yùn)算符…等,以下就是總結(jié)的常用基礎(chǔ)知識(shí)2019-02-02

