你不知道的JavaScript【上】(Part1)第一章 作用域

作用域

一套設(shè)計(jì)良好的規(guī)則來(lái)存儲(chǔ)變量,并且方便之后再找到變量。這套規(guī)則叫做作用域。

1. 編譯原理

通常認(rèn)為JavaScript是“動(dòng)態(tài)”||“解釋執(zhí)行”的語(yǔ)言,事實(shí)上是一門編譯語(yǔ)言。不過(guò)其并非提前編譯的,編譯的結(jié)果也不能再分布式系統(tǒng)中移植運(yùn)行。
JavaScript引擎編譯步驟

  • 分詞/詞法分析
    將字符串分解為(對(duì)編程語(yǔ)言來(lái)說(shuō))有意義的代碼塊(即詞法單元)
  • 解析/語(yǔ)法分析
    將詞法單元流(數(shù)組)轉(zhuǎn)換成“抽象語(yǔ)法樹(shù)”(AST)
  • 代碼生成
    將AST轉(zhuǎn)換為可執(zhí)行代碼的過(guò)程為代碼生成

簡(jiǎn)單來(lái)說(shuō)就是有某種方法可以將var a = 2;的AST 轉(zhuǎn)化為一組機(jī)器指令,用來(lái)創(chuàng)建一個(gè)叫作a 的變量(包括分配內(nèi)存等),并將一個(gè)值儲(chǔ)存在a 中。

任何JavaScript代碼片段在執(zhí)行前都要編譯,大多是發(fā)生在執(zhí)行前幾微秒

2. 理解作用域

  • 引擎
    從頭到尾負(fù)責(zé)整個(gè)JavaScript程序的編譯及執(zhí)行過(guò)程
  • 編譯器
    輔助詞法分析&代碼生成
  • 作用域
    負(fù)責(zé)收集&維護(hù)所有聲明的標(biāo)識(shí)符(變量)組成的一系列查詢,并實(shí)施非常嚴(yán)格的規(guī)則,確定當(dāng)前執(zhí)行代碼對(duì)這些變量的訪問(wèn)權(quán)限。

對(duì)var a = 2;的分解

  1. 編譯器先將這段代碼分解為詞法單元,再將詞法單元解析成一個(gè)樹(shù)結(jié)構(gòu)
  2. 遇到var a,編譯器會(huì)詢問(wèn)作用域是否存在同名變量。是->忽略該聲明,繼續(xù)編譯;否->在當(dāng)前作用域的集合中聲明一個(gè)新的變量,并命名為a
  3. 接下來(lái),編譯器會(huì)為引擎生成運(yùn)行時(shí)所需代碼,用來(lái)處理a = 2的操作。引擎運(yùn)行時(shí)會(huì)先詢問(wèn)作用域,在當(dāng)前作用域集合中是否存在叫a的變量,是->引擎使用此變量;否->引擎繼續(xù)查找;如未找到,會(huì)拋出異常

總結(jié):變量的賦值會(huì)執(zhí)行兩個(gè)動(dòng)作,首先在當(dāng)前作用域中聲明變量(如之前未聲明過(guò)),然后運(yùn)行時(shí),引擎在作用域中查找該變量,如果找到則進(jìn)行賦值。

LHS查詢&RHS查詢

根據(jù)變量在賦值操作(=)的左右側(cè)分為,LHS和RHS

  • RHS是取值,查找源值
  • LHS是取容器,找到目標(biāo)

函數(shù)聲明function foo(a) {...不是LHS查詢
var foo、 foo = function(a) {...是LHS查詢

function foo(a) {
var b = a;
return a + b;
}
var c = foo( 2 );

這其中有3處LHS和4出RHS
LHS: c=... | a=... | b=...
RHS: foo(2) | =a | a+ | +b

3. 作用域嵌套

在當(dāng)前作用域中無(wú)法找到某個(gè)變量,就會(huì)向外層作用域查找,直到找到該變量或抵達(dá)最外層的作用域(全局作用域)

4. 異常

ES5中引入了“嚴(yán)格模式”,在正常模式|“寬松模式“|”懶惰模式”下,如果找到全局作用域還是找不到變量,會(huì)自動(dòng)或隱式地創(chuàng)建全局變量。
而在“嚴(yán)格模式”下,不會(huì)創(chuàng)建并返回一個(gè)全局變量,引擎會(huì)拋出ReferenceError異常。

嚴(yán)格模式下,禁止自動(dòng)或隱式地創(chuàng)建全局變量

小結(jié)

  1. 作用域是一套規(guī)則,用于確定在何處以及如何查找變量(標(biāo)識(shí)符)
  2. 查找的目的是對(duì)變量賦值,則是LHS查詢;目的是獲取變量的值則是RHS查詢
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容