JavaScript中的LHS和RHS分析詳情
前言:
對(duì)于LHS和RHS,從字面意思來(lái)說(shuō)是?? Left Hand Side?
?和?? Right Hand Side?
?即左手邊和右手邊,一般可以理解為賦值操作的左側(cè)和右側(cè),然而不能片面的用??=?
?號(hào)左邊還說(shuō)右邊去判斷是??LHS?
?還是??RHS?
?通俗的理解,?
?LHS?
?是賦值操作即可以看做是在往內(nèi)存中存儲(chǔ)值,而??RHS?
?是取值操作,它是從內(nèi)存中進(jìn)行檢索。事實(shí)上賦值操作還有其他幾種形式,因此在概念上最好將其理解為“賦值操作的目標(biāo)是誰(shuí)(LHS)”以及“誰(shuí)是賦值操作的源頭(RHS)”。
進(jìn)一步理解
這兩種不同的引用方式對(duì)沒(méi)有聲明的變量的處理方式上是不同的,而這個(gè)不同之處對(duì)于我們編寫(xiě)代碼和分析JS引擎報(bào)錯(cuò)是很有益處的。 當(dāng)對(duì)一個(gè)變量執(zhí)行??RHS?
?查詢時(shí),如果遍歷該變量所在處的詞法作用域未能找到這個(gè)變量,JS引擎就會(huì)拋出?? ReferenceError?
?錯(cuò)誤如果成功查詢到了這個(gè)變量,但是對(duì)這個(gè)變量執(zhí)行不合理操作,比如對(duì)一個(gè)非數(shù)組的變量執(zhí)行下標(biāo)取值,JS引擎就會(huì)拋出?? TypeError?
?錯(cuò)誤,甚至跟你說(shuō)這個(gè)操作對(duì)應(yīng)的只能是數(shù)組。當(dāng)對(duì)一個(gè)變量執(zhí)行?
?LHS?
?查詢時(shí),同樣在遍歷作用域后無(wú)法找到該變量,在非??ES5?
?的嚴(yán)格模式下,系統(tǒng)就會(huì)自動(dòng)在全局作用域中創(chuàng)建一個(gè)同名變量,并將引用轉(zhuǎn)移到該新建的全局變量中。而在??ES5?
?的嚴(yán)格模式下,LHS查詢失敗時(shí)JS引擎會(huì)拋出一個(gè)同RHS一樣的?? ReferenceError ?
?錯(cuò)誤。![?
因此,對(duì)LHS查詢和RHS查詢的仔細(xì)區(qū)分和理解無(wú)論是對(duì)JS執(zhí)行過(guò)程本身的理解還是分析錯(cuò)誤都是有所好處的。
在JS語(yǔ)言特點(diǎn)
JavaScript在類型上通常會(huì)被歸類為“動(dòng)態(tài)”或“解釋執(zhí)行”語(yǔ)言,但事實(shí)上它是一門編譯語(yǔ)言。
JavaScript是世界上最流行的腳本語(yǔ)言,因?yàn)槟阍陔娔X、手機(jī)、平板上瀏覽的所有的網(wǎng)頁(yè),以及無(wú)數(shù)基于HTML5的手機(jī)App,交互邏輯都是由JavaScript驅(qū)動(dòng)的。
簡(jiǎn)單地說(shuō),JavaScript是一種運(yùn)行在瀏覽器中的解釋型的編程語(yǔ)言。
不過(guò)這種語(yǔ)言與傳統(tǒng)的編譯語(yǔ)言還是有點(diǎn)不同,它不是提前編譯的,編譯結(jié)果也不能在分布式系統(tǒng)上進(jìn)行移植,做過(guò)前端項(xiàng)目部署的同學(xué),也會(huì)發(fā)現(xiàn),我們將項(xiàng)目編譯完成之后是個(gè)??dist?
?文件,之后將這整個(gè)文件直接放在web服務(wù)器上面,如nginx、tomcat等,這個(gè)是個(gè)很純粹的單機(jī)部署。
編譯特點(diǎn)
比如說(shuō),執(zhí)行一個(gè)賦值語(yǔ)句,我們的JavaScript引擎要做多少事呢?
var girlfriend = 'naug'
事實(shí)上做了兩步,JavaScript 會(huì)將其看成兩句聲明:??var girlfriend;?
?和??girlfriend = 'naug';?
?
- 定義聲明在編譯階段進(jìn)行
- 賦值聲明會(huì)被留在原地等待執(zhí)行階段。
分析
變量的賦值操作會(huì)執(zhí)行兩個(gè)動(dòng)作,首先編譯器會(huì)在當(dāng)前作用域中聲明一個(gè)變量(如果之前沒(méi)有聲明過(guò)),然后在運(yùn)行時(shí)引擎會(huì)在作用域中查找該變量,如果能夠找到就會(huì)對(duì)它賦值。 而要講的LHS 和 RHS就是上面說(shuō)的對(duì)變量的兩種查找操作,查找的過(guò)程是由作用域(詞法作用域)進(jìn)行協(xié)助,在編譯的第二步中執(zhí)行。 前面我們說(shuō)到,??LHS?
?是賦值操作就是在往內(nèi)存中存儲(chǔ)值,而??RHS?
?是取值操作可以從內(nèi)存中檢索值,那么基于這個(gè)信息點(diǎn),我們?cè)賮?lái)分析一個(gè)復(fù)雜一些的例子
function together(people) { var girlFriend = people; return girlFriend } var luckyGirl = together('naug');
問(wèn),這個(gè)例子中一共用了多少個(gè)LHS和RHS? 答,3個(gè)LHS和3個(gè)RHS
- LHS
- 函數(shù)里面隱藏的??people = 'naug'?
?(隱式變量分配),當(dāng)調(diào)用??together('naug')?
?時(shí),需要將實(shí)參??naug?
?賦值給形參??people?
?,所以對(duì)??people?
?需要進(jìn)行??LHS?
?操作 - 對(duì)于?
?girlFriend = people?
? ,中,girlFriend在賦值操作的左邊,即將該變量往該作用域空間所在內(nèi)存區(qū)間儲(chǔ)值,也就是進(jìn)行LHS操作 - ?
?luckyGirl = ... ?
?,中??luckyGirl?
?在賦值操作的左邊,需要為該變量在內(nèi)存中進(jìn)行儲(chǔ)值,即對(duì)??luckyGirl?
?進(jìn)行??LHS?
?操作
- RHS
- ??girlFriend = people?
? ,中??people?
?在賦值操作的右邊,??javascript?
?引擎需要對(duì)其進(jìn)行取值操作,因此進(jìn)行??RHS?
?查詢 - ?
?return girlFriend?
?,由于需要知道??girlfriend?
?的值,因此進(jìn)行??RHS?
?查詢到??girlfriend?
?的值 - ?
?luckyGirl = together('naug')?
?,中??together('naug')?
?在賦值操作的右邊因此需要知道該函數(shù)執(zhí)行之后的值 小結(jié):如果查找的目的是對(duì)變量進(jìn)行賦值,那么就會(huì)使用LHS查詢;如果目的是獲取變量的值,就會(huì)使用RHS查詢。
區(qū)分 LHS 和 RHS 的重要性
因?yàn)樵谧兞窟€沒(méi)有聲明(在任何作用域中都無(wú)法找到該變量)情況下,這兩種查詢行為是不一樣的。 對(duì)于作用域的分析可以看一下這篇文章? ?關(guān)于JS中的作用域??,這里想說(shuō)的是LHS和RHS都會(huì)在當(dāng)前執(zhí)行作用域中開(kāi)始,如果有需要(也就是說(shuō)他們沒(méi)有找到所需的標(biāo)識(shí)符),就會(huì)向上級(jí)作用域繼續(xù)查找目標(biāo)標(biāo)識(shí)符,依次上升一次作用域,最后抵達(dá)全局作用域,最后無(wú)論找到或沒(méi)找到都將到此為止
總結(jié):
不成功的RHS引用會(huì)導(dǎo)致拋出??ReferenceError?
?異常。不成功的LHS引用會(huì)導(dǎo)致自動(dòng)隱式地創(chuàng)建一個(gè)全局變量(非嚴(yán)格模式下),該變量使用LHS引用的目標(biāo)作為標(biāo)識(shí)符,或者拋出??ReferenceError?
?異常(嚴(yán)格模式下)。
到此這篇關(guān)于JavaScript中的LHS和RHS分析詳情的文章就介紹到這了,更多相關(guān)JavaScript中的LHS和RHS內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于JavaScript中forEach和each用法淺析
這篇文章主要給大家介紹了關(guān)于JavaScript中forEach和each使用方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-07-07js替換字符串中所有指定的字符(實(shí)現(xiàn)代碼)
下面小編就為大家?guī)?lái)一篇js替換字符串中所有指定的字符(實(shí)現(xiàn)代碼)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08JavaScript實(shí)現(xiàn)京東購(gòu)物放大鏡和選項(xiàng)卡效果的方法分析
這篇文章主要介紹了JavaScript實(shí)現(xiàn)京東購(gòu)物放大鏡和選項(xiàng)卡效果的方法,結(jié)合實(shí)例形式分析了javascript基于事件響應(yīng)、數(shù)值計(jì)算與頁(yè)面元素動(dòng)態(tài)修改實(shí)現(xiàn)圖片放大功能以及tab選項(xiàng)卡切換效果相關(guān)操作技巧,需要的朋友可以參考下2018-07-07CountUp.js數(shù)字滾動(dòng)插件使用方法詳解
這篇文章主要為大家詳細(xì)介紹了CountUp.js數(shù)字滾動(dòng)插件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10遍歷json 對(duì)象的屬性并且動(dòng)態(tài)添加屬性的實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇遍歷json 對(duì)象的屬性并且動(dòng)態(tài)添加屬性的實(shí)現(xiàn)。小編覺(jué)的挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12JS小功能(操作Table--動(dòng)態(tài)添加刪除表格及數(shù)據(jù))實(shí)現(xiàn)代碼
這篇文章主要介紹了操作Table--動(dòng)態(tài)添加刪除表格及數(shù)據(jù)實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-11-11JavaScript ECMA-262-3 深入解析.第三章.this
在這篇文章里,我們將討論跟執(zhí)行上下文直接相關(guān)的更多細(xì)節(jié)。討論的主題就是this關(guān)鍵字2011-09-09