【知識點】LHS與RHS

LHS與RHS

爲了解釋這兩個術語,咱們以拍電影爲例,這部戲中有三個角色:bash

  • 做用域(男一號):負責收集並維護由全部聲明的標識符(變量)組成的一系列查詢,並實施一套很是嚴格的規則,肯定當前執行的代碼對這些標識符的訪問權限。函數

  • 引擎(男二號):從頭至尾負責整個 JavaScript 程序的編譯及執行過程。spa

  • 編譯器(男二號):負責語法分析及代碼生成等髒活累活。code

劇本是對象

var a = 2
複製代碼

第一場戲:

遇到 var a,編譯器會詢問做用域是否已經有一個該名稱的變量存在於同一個做用域的 集合中。ip

若是是,編譯器會忽略該聲明,繼續進行編譯;作用域

不然它會要求做用域在當前做用域的集合中聲明一個新的變量,並命名爲 a。編譯器

接下來編譯器會爲引擎生成運行時所需的代碼,這些代碼被用來處理 a = 2 這個賦值 操做。io

第二場戲

引擎運行時會首先詢問做用域,在當前的做用域集合中是否存在一個叫做 a 的 變量。console

若是是,引擎就會使用這個變量;

若是否,引擎會繼續查找該變量。

引擎要加戲

好了戲拍完了,可是引擎感受本身的戲不夠多,因而它找到導演要求加戲。

引擎:導演,拍第二場戲的時候我找變量a的方式並沒體現出來,我以爲我有必要演一下。

導演:哦,你想怎麼演?

引擎:我有兩種方式來表現這個查找過程,第一種叫作LHS,第二種叫作RHS。

導演:那你以爲在我們這部戲中(var a = 2)用哪一種方式呢?

引擎:用LHS,由於LHS是試圖找到變量的容器自己,從而能夠對其賦值,用在我們這戲中正好。

導演:那RHS呢?

引擎:RHS與簡單地查找某個變量的值別無二致,能夠理解爲取到某某的源值。

導演:你給個場景,我理解一下。

引擎:例如我以前拍的那部戲 conselo.log(a),爲了找到a的值,我就要使用RHS來表現這個查找過程。

導演:聽起來不錯,下場戲你表現一下給我看看。

下一場戲

劇本:

function foo(a) {
console.log( a ); // 2
}
foo( 2 );
複製代碼

引擎:我說做用域,我須要爲 foo 進行 RHS 引用。你見過它嗎?

做用域:別說,我還真見過,編譯器那小子剛剛聲明瞭它。它是一個函數,給你。

引擎:哥們太夠意思了!好吧,我來執行一下 foo。

引擎:做用域,還有個事兒。我須要爲 a 進行 LHS 引用,這個你見過嗎?

做用域:這個也見過,編譯器最近把它聲名爲 foo 的一個形式參數了,拿去吧。

引擎:大恩不言謝,你老是這麼棒。如今我要把 2 賦值給 a。

引擎:哥們,很差意思又來打擾你。我要爲 console 進行 RHS 引用,你見過它嗎?

做用域:咱倆誰跟誰啊,再說我就是幹這個。這個我也有,console 是個內置對象。 給你。

引擎:麼麼噠。我得看看這裏面是否是有 log(..)。太好了,找到了,是一個函數。

引擎:哥們,能幫我再找一下對 a 的 RHS 引用嗎?雖然我記得它,但想再確認一次。

做用域:放心吧,這個變量沒有變更過,拿走,不謝。

引擎:真棒。我來把 a 的值,也就是 2,傳遞進 log(..)。

...

爲何區分 LHS 和 RHS 是一件重要的事情?

緣由是兩者對沒有找到的變量的異常處理方式不一樣。

若是 RHS 查詢在全部嵌套的做用域中遍尋不到所需的變量,引擎就會拋出 ReferenceError 異常。

當引擎執行 LHS 查詢時,若是在頂層(全局做用域)中也沒法找到目標變量, 全局做用域中就會建立一個具備該名稱的變量,並將其返還給引擎,前提是程序運行在非 「嚴格模式」下。

總結

LHS:賦值操做的目標是誰。

RHS:誰是賦值操做的源頭。

LHS 和 RHS 查詢都會在當前執行做用域中開始,若是有須要(也就是說它們沒有找到所 需的標識符),就會向上級做用域繼續查找目標標識符,這樣每次上升一級做用域(一層 樓),最後抵達全局做用域(頂層),不管找到或沒找到都將中止。

不成功的 RHS 引用會致使拋出 ReferenceError 異常。

不成功的 LHS 引用會致使自動隱式地建立一個全局變量(非嚴格模式下),該變量使用 LHS 引用的目標做爲標識符,或者拋出 ReferenceError 異常(嚴格模式下)。

注:以上部份內容來自於《你不知道的Javascript》

相關文章
相關標籤/搜索