成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JS編譯之 LHS RHS(你不知道的JavaScript 小記一)

Cristic / 3358人閱讀

摘要:關(guān)于兩個(gè)專(zhuān)業(yè)術(shù)語(yǔ)的討論起自對(duì)你不知道的一書(shū)的閱讀學(xué)習(xí)。遇到,編譯器會(huì)詢(xún)問(wèn)作用域是否已經(jīng)有一個(gè)該名稱(chēng)的變量存在于同一個(gè)作用域的集合中。摘錄來(lái)自你不知道的。

JS 編譯之 LHS RHS 一、前言

最近和朋友聊技術(shù)的時(shí)候,聊到 LHS RHS,我竟然沒(méi)聽(tīng)說(shuō)過(guò) 沒(méi)聽(tīng)說(shuō)過(guò)。。。 于是成功引起了我的好奇心。 關(guān)于兩個(gè)專(zhuān)業(yè)術(shù)語(yǔ)的討論起自對(duì)《你不知道的JavaScript》一書(shū)的閱讀學(xué)習(xí)。

二、編譯簡(jiǎn)述

盡管通常將JavaScript歸類(lèi)為“動(dòng)態(tài)”或“解釋執(zhí)行”語(yǔ)言,但事實(shí)上它是一門(mén)編譯語(yǔ)言。這個(gè)事實(shí)對(duì)你來(lái)說(shuō)可能顯而易見(jiàn),也可能你聞所未聞,取決于你接觸過(guò)多少編程語(yǔ)言,具有多少經(jīng)驗(yàn)。但與傳統(tǒng)的編譯語(yǔ)言不同,它不是提前編譯的,編譯結(jié)果也不能在分布式系統(tǒng)中進(jìn)行移植。

盡管如此,JavaScript引擎進(jìn)行編譯的步驟和傳統(tǒng)的編譯語(yǔ)言非常相似,在某些環(huán)節(jié)可能比預(yù)想的要復(fù)雜。

在傳統(tǒng)編譯語(yǔ)言的流程中,程序中的一段源代碼在執(zhí)行之前會(huì)經(jīng)歷三個(gè)步驟,統(tǒng)稱(chēng)為“編譯”。

分詞/詞法分析(Tokenizing/Lexing)

解析/語(yǔ)法分析(Parsing)

代碼生成

比起那些編譯過(guò)程只有三個(gè)步驟的語(yǔ)言的編譯器,JavaScript引擎要復(fù)雜得多。例如,在語(yǔ)法分析和代碼生成階段有特定的步驟來(lái)對(duì)運(yùn)行性能進(jìn)行優(yōu)化,包括對(duì)冗余元素進(jìn)行優(yōu)化等。

JavaScript引擎,編譯器概述

從頭到尾負(fù)責(zé)整個(gè)JavaScript程序的編譯及執(zhí)行過(guò)程。

引擎的好朋友之一,負(fù)責(zé)語(yǔ)法分析及代碼生成等臟活累活。

摘錄來(lái)自: “你不知道的JavaScript(上卷)”

以上內(nèi)容看起來(lái)有些高深,但是與下面內(nèi)容并無(wú)多少關(guān)聯(lián),只是背景,有興趣的可以深入研究一下。
對(duì)于下面的內(nèi)容,我們只需要知道 JS代碼的執(zhí)行需要JS引擎的,而JS引擎的在執(zhí)行代碼前會(huì)先對(duì)其進(jìn)行編譯(有些地方稱(chēng)之為預(yù)解析),引擎最終執(zhí)行的是經(jīng)過(guò)編譯之后的代碼。
LHS RHS 這兩個(gè)術(shù)語(yǔ)就是出現(xiàn)在引擎對(duì)變量進(jìn)行查詢(xún)的時(shí)候,接下來(lái)看看在具體例子中 站在編譯器和引擎的角度看看它們是怎么思考工作的,以及這個(gè)過(guò)程中如何觸發(fā)了LHS RHS.

三、具體代碼的編譯執(zhí)行過(guò)程中 如何觸發(fā) LHS RHS

以書(shū)中的賦值語(yǔ)句為示例

var a = 2;

事實(shí)上編譯器會(huì)進(jìn)行如下處理。

遇到var a,編譯器會(huì)詢(xún)問(wèn)作用域是否已經(jīng)有一個(gè)該名稱(chēng)的變量存在于同一個(gè)作用域的集合中。如果是,編譯器會(huì)忽略該聲明,繼續(xù)進(jìn)行編譯;否則它會(huì)要求作用域在當(dāng)前作用域的集合中聲明一個(gè)新的變量,并命名為a。

接下來(lái)編譯器會(huì)為引擎生成運(yùn)行時(shí)所需的代碼,這些代碼被用來(lái)處理a = 2這個(gè)賦值操作。引擎運(yùn)行時(shí)會(huì)首先詢(xún)問(wèn)作用域,在當(dāng)前的作用域集合中是否存在一個(gè)叫作a的變量。如果是,引擎就會(huì)使用這個(gè)變量;如果不是,引擎會(huì)繼續(xù)查找該變量。

摘錄來(lái)自: 你不知道的JavaScript。

以上為書(shū)中描述,但是個(gè)人覺(jué)得可以補(bǔ)充一些描述如下

編譯器在編譯一段js代碼時(shí),相當(dāng)于對(duì)這段代碼進(jìn)行預(yù)解析,為了引擎更好的進(jìn)行二次解析。在預(yù)解析時(shí),先構(gòu)建好代碼的上下文環(huán)境,建立作用域鏈,在每個(gè)作用域中進(jìn)行變量聲明提升和更特別的函數(shù)聲明提升。變量的聲明提升會(huì)在當(dāng)前作用域的集合中聲明一個(gè)新的變量,如a。另外,在聲明每一個(gè)新的變量之前,編譯器會(huì)詢(xún)問(wèn)作用域是否已經(jīng)有一個(gè)該名稱(chēng)的變量存在于同一個(gè)作用域的集合中, 如有則報(bào)錯(cuò)。

   console.log(a)
   var a = 2;

的預(yù)解析之后,其實(shí)相當(dāng)于

var a
console.log(a) // undefined
a = 2;

接下來(lái)編譯器會(huì)為引擎生成運(yùn)行時(shí)所需的代碼,這些代碼被用來(lái)處理a = 2這個(gè)賦值操作。引擎運(yùn)行時(shí)會(huì)首先詢(xún)問(wèn)作用域,在當(dāng)前的作用域集合中是否存在一個(gè)叫作a的變量。如果是,引擎就會(huì)使用這個(gè)變量;如果不是,引擎會(huì)沿作用域鏈繼續(xù)查找該變量;如果查到根作用域也沒(méi)有查到,會(huì)自動(dòng)聲明a。

ps: 關(guān)于聲明提升,作用域鏈,如有疑惑,后續(xù)章節(jié)解釋。

上述過(guò)程中,第二步中編譯器生成了代碼,引擎執(zhí)行它時(shí)(第3行 a = 2),會(huì)通過(guò)查找變量a來(lái)判斷它是否已聲明過(guò)。查找的過(guò)程由作用域進(jìn)行協(xié)助,但是引擎執(zhí)行怎樣的查找,會(huì)影響最終的查找結(jié)果。
此時(shí)引擎會(huì)就在對(duì)變量a進(jìn)行LHS查詢(xún),另外一個(gè)查詢(xún)的類(lèi)型叫RHS。

四、LHS RHS 概念定義
我打賭你一定能猜到“L”和“R”的含義,它們分別代表左側(cè)和右側(cè)。
什么東西的左側(cè)和右側(cè)?是一個(gè)賦值操作的左側(cè)和右側(cè)。

換句話(huà)說(shuō),當(dāng)變量出現(xiàn)在賦值操作的左側(cè)時(shí)進(jìn)行LHS查詢(xún),出現(xiàn)在右側(cè)時(shí)進(jìn)行RHS查詢(xún)。

講得更準(zhǔn)確一點(diǎn),RHS查詢(xún)與簡(jiǎn)單地查找某個(gè)變量的值別無(wú)二致,而LHS查詢(xún)則是試圖找到變量的容器本身,從而可以對(duì)其賦值。從這個(gè)角度說(shuō),RHS并不是真正意義上的“賦值操作的右側(cè)”,更準(zhǔn)確地說(shuō)是“非左側(cè)”。

你可以將RHS理解成retrieve his source value(取到它的源值),這意味著“得到某某的值”。

LHS和RHS的含義是“賦值操作的左側(cè)或右側(cè)”并不一定意味著就是“=賦值操作符的左側(cè)或右側(cè)”。賦值操作還有其他幾種形式,因此在概念上最好將其理解為“賦值操作的目標(biāo)是誰(shuí)(LHS)”以及“誰(shuí)是賦值操作的源頭(RHS)”。

摘錄來(lái)自: 你不知道的JavaScript。

以上為書(shū)中解釋?zhuān)再x值操作符為標(biāo)志,加上一些特殊情況的理解。但是我覺(jué)得可以有其他的理解方式。

五、LHS RHS 個(gè)人理解
講得更準(zhǔn)確一點(diǎn),RHS查詢(xún)與簡(jiǎn)單地查找某個(gè)變量的值別無(wú)二致,而LHS查詢(xún)則是試圖找到變量的容器本身,從而可以對(duì)其賦值。

舉個(gè)例子來(lái)理解就是:RHS是找到你在哪個(gè)座位,看看你的樣子拍個(gè)照;LHS同樣是找到你在哪個(gè)座位,但是一眼不看直接踹飛 換個(gè)人坐這兒。
簡(jiǎn)單來(lái)講有兩個(gè)區(qū)別:1.關(guān)不關(guān)心你現(xiàn)在的狀態(tài) 2.是否改變你的狀態(tài)(不管是改變一部分,還是完全改變)。

所以書(shū)中這句原話(huà)

是引擎執(zhí)行怎樣的查找,會(huì)影響最終的查找結(jié)果。

我覺(jué)得可以反過(guò)來(lái)理解,正是因?yàn)椴檎医Y(jié)果的不同分出了兩種查找類(lèi)型。

左側(cè)右側(cè)的分類(lèi)理解更多是以 代碼的形態(tài)為標(biāo)準(zhǔn)分類(lèi)的。個(gè)人覺(jué)得可以按查找目的為標(biāo)準(zhǔn)分類(lèi),RHS是為了讀取變量的值,LHS是為了改變變量的值。

六、總結(jié)

LHS RHS就是對(duì)變量查詢(xún)的兩種查詢(xún)類(lèi)型,區(qū)別在于查詢(xún)的結(jié)果,或者說(shuō)查詢(xún)的目的,在代碼上直觀體現(xiàn)為變量位置形態(tài)的不同。其中涉及的編譯器引擎工作過(guò)程,對(duì)于更深入的理解掌握js很有幫助。 其中個(gè)人理解有不合適的地方還請(qǐng)指正。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96096.html

相關(guān)文章

  • javascript作用域和閉包我見(jiàn)

    摘要:查詢(xún)是在作用域鏈中,一級(jí)級(jí)的往上查找該變量的引用。作用域和作用域鏈作用域的概念,應(yīng)該兩張圖幾句話(huà)就能解釋吧。這個(gè)建筑代表程序中的嵌套作用域鏈。一層嵌一層的作用域形成了作用域鏈,變量在作用域鏈中的函數(shù)內(nèi)得到了自己的定義。 javascript作用域和閉包之我見(jiàn) 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和閉包,感受頗深,遂寫(xiě)一篇讀書(shū)筆記加深印象。路過(guò)的大牛歡迎指點(diǎn)...

    SoapEye 評(píng)論0 收藏0
  • 讀書(shū)筆記-你不知道JavaScript(上)

    摘要:比如程序會(huì)被分解為解析語(yǔ)法分析將詞法單元流轉(zhuǎn)換成一個(gè)由元素逐級(jí)嵌套所組成的代表了程序語(yǔ)法接口的書(shū),又稱(chēng)抽象語(yǔ)法樹(shù)。代碼生成將抽象語(yǔ)法樹(shù)轉(zhuǎn)換為機(jī)器能夠識(shí)別的指令。 showImg(https://segmentfault.com/img/remote/1460000009682106?w=640&h=280); 本文首發(fā)在我的個(gè)人博客:http://muyunyun.cn/ 《你不知道的...

    jzzlee 評(píng)論0 收藏0
  • JS學(xué)習(xí)系列 01 - 編譯原理和作用域

    摘要:的抽象語(yǔ)法樹(shù)中可能如下圖所示代碼生成將轉(zhuǎn)換為可執(zhí)行代碼的過(guò)程被稱(chēng)為代碼生成。如果是,編譯器會(huì)忽略該聲明,繼續(xù)進(jìn)行編譯,否則它會(huì)要求在當(dāng)前作用域的集合中聲明一個(gè)新的變量,并命名為。 在學(xué)習(xí) javascript 的過(guò)程中,我們第一步最應(yīng)該了解和掌握的就是作用域,與之相關(guān)還有程序是怎么編譯的,變量是怎么查找的,js 引擎是什么,引擎和作用域的關(guān)系又是什么,這些是 javascript 這門(mén)...

    jkyin 評(píng)論0 收藏0
  • 快速理解JavaScript LHSRHS 查詢(xún)

    摘要:如果查找的目的是對(duì)變量進(jìn)行賦值,就會(huì)使用查詢(xún)?nèi)绻康氖谦@取變量的值,就會(huì)用查詢(xún)。賦值操作會(huì)導(dǎo)致查詢(xún)。接下來(lái),會(huì)查詢(xún)查詢(xún)變量并對(duì)其進(jìn)行賦值。不成功的引用會(huì)導(dǎo)致拋出異常。 簡(jiǎn)述編譯原理 JavaScript 程序中的一段源代碼在執(zhí)行之前會(huì)經(jīng)歷三個(gè)步驟,統(tǒng)稱(chēng)為 編譯 分詞/詞法分析 解析/語(yǔ)法分析 代碼生成 先看原書(shū)對(duì)一個(gè)賦值操作的拆解說(shuō)明: 變量的賦值操作會(huì)執(zhí)行兩個(gè)動(dòng)作,首先編譯器會(huì)...

    lemon 評(píng)論0 收藏0
  • 重讀你不知道JS (上) 第節(jié)

    摘要:的抽象語(yǔ)法樹(shù)中可能會(huì)有一個(gè)叫作的頂級(jí)節(jié)點(diǎn),接下來(lái)是一個(gè)叫作它的值是的子節(jié)點(diǎn),以及一個(gè)叫作的子節(jié)點(diǎn)。值得注意的是,是非常重要的異常類(lèi)型。嚴(yán)格模式下,未聲明的和倆者行為相同,都會(huì)是。 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門(mén)充滿(mǎn)吸引力、簡(jiǎn)單易用的語(yǔ)言,又是一門(mén)具有許多復(fù)雜微妙技術(shù)的語(yǔ)言,即使是經(jīng)驗(yàn)豐富的 JavaScript 開(kāi)發(fā)者,如果...

    lk20150415 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<