javascript
JavaScript中的LHS和RHS查询
文章是本人大三期間的學習筆記,一些論斷取自書籍和網上博客,礙于當時的技術水平有一些寫得不夠好的地方,可以在評論處理智討論~
問題來源于《你不知道的JavaScript(上卷)》,文章部分論述截自原書。
簡述編譯原理
JavaScript通常會被歸類為“動態”或“解釋執行”語言,但事實上它是一門編譯語言。但與傳統的編譯語言不同,它不是提前編譯的,編譯結果也不能在分布式系統上進行移植。
在傳統編譯語言的流程中,程序中的一段源代碼在執行前會經歷三個步驟,統稱為“編譯”。
與其他語言不同,JavaScript的編譯過程不是發生在構建之前的。對于JavaScript來說,大部分情況下編譯發生在代碼執行前的幾微秒(甚至更短)的時間內。
舉個栗子,var a = 2; JavaScript引擎會將它分為幾步完成呢?
??答案是兩步,JavaScript 會將其看成兩句聲明:var a; 和 a = 2;。第一個定義聲明在編譯階段進行,第二個賦值聲明會被留在原地等待執行階段。
下面是原書對這句聲明的拆解分析:
變量的賦值操作會執行兩個動作,首先編譯器會在當前作用域中聲明一個變量(如果之前沒有聲明過),然后在運行時引擎會在引用域中查找該變量,如果能夠找到就會對它賦值。
而要講的LHS 和 RHS 就是上面說的對變量的兩種查找操作,查找的過程是由作用域(詞法作用域)進行協助,在編譯的第二步中執行。
LHS 和 RHS
LHS(Left-hand Side)引用和RHS(Right-hand Side)引用。通常是指等號(賦值運算)的左右邊的引用。
我們來看下面這句代碼:
這里對a的引用是一個RHS引用,因為這里a并沒有賦予任何值,我們只是想查找并取得a的值,然后將它打印出來。
a = 2;這里對a的引用是一個LHS引用,因為我們并不關心當前的值是什么,只是想要為賦值操作找到目標。
注:LHS和RHS的含義是“賦值操作的左側和右側”并不一定意味這就是"="的左側和右側。賦值操作還有其他幾種形式,因此在概念上最好將其理解為“賦值操作的目標是誰(LHS)”以及“誰是賦值操作的源頭(RHS)”。
這里再舉一個較復雜的例子:(找出所有的LHS查詢和所有的RHS查詢)
function foo(a) {var b = a;return a + b; }var c = foo(2);這里一共有3個LHS查詢和4個RHS查詢,這里我們都來做個分析。
LHS:
RHS:
小結:如果查找的目的是對變量進行賦值,那么就會使用LHS查詢;
???如果目的是獲取變量的值,就會使用RHS查詢。
區分 LHS 和 RHS 的重要性
因為在變量還沒有聲明(在任何作用域中都無法找到該變量)情況下,這兩種查詢行為是不一樣的。
LHS 和 RHS 查詢都會在當前執行作用域中開始,如果有需要(也就是說他們沒有找到所需的標識符),就會向上級作用域繼續查找目標標識符,這樣每次上升一次作用域,最后抵達全局作用域,無論找到或沒找到都將停止。
借用書中的一張圖,將作用域鏈比喻成一個建筑,在對上面的論述進行一次轉換。
(對作用域鏈的具體介紹可以移步 理解 JavaScript 的作用域鏈)
這個建筑代表儲蓄中的嵌套作用域鏈。第一層樓代表當前的執行作用域,也就是你所在的位置。建筑的頂層代表全局作用域。
LHS 和 RHS 引用都會在當前樓層進行查找,如果沒有找到,就會坐電梯前往上一層樓,如果還是沒有找到就繼續向上,以此類推。一旦抵達頂層(全局作用域),可能找到了你所需的變量,也可能沒找到,但無論如何查找過程都將停止。
總結:不成功的RHS引用會導致拋出 ReferenceError 異常。不成功的LHS引用會導致自動隱式地創建一個全局變量(非嚴格模式下),該變量使用LHS引用的目標作為標識符,或者拋出 ReferenceError 異常(嚴格模式下)。
總結
以上是生活随笔為你收集整理的JavaScript中的LHS和RHS查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: R语言数据合并
- 下一篇: vim全文替换字符串