JavaScript的LHS和RHS查詢

var number = 1;
複製代碼

當你看到這段代碼的時候,你可能簡單的認爲是爲變量\color{red}{number賦值爲1}。事實上,這裏是分爲兩個階段處理,\color{red}{一個是編譯器編譯處理,一個是引擎運行處理}。是由編譯器和引擎協助工做。bash

  • 首先將分詞/詞法分析這段代碼分解爲詞法單元。
  • 而後解析語法分析,生成一個抽象語法樹-AST。
  • 最後進行代碼生成。

引擎:負責整個JavaScript的編譯和執行過程。函數

編譯器:負責JavaScript的語法分析和代碼生成。post

1、編譯器生成代碼時作了什麼?

  1. 碰見var number,編譯器會詢問做用域中是夠已經有一個名稱爲number的變量存在於當前做用域中,若是存在,會忽略當前聲明。若是不存在就是在當前做用域聲明一個變量number。這這個階段是進行變量提高的一個過程【JavaScript變量提高運行機制】。測試

  2. 而後編譯器會生成引擎運行時須要的代碼。生成代碼用來處理賦值的操做。ui

  3. 引擎運行時,首先會詢問當前做用域是否有一個變量number,若是有直接使用這個變量。若是沒有,引擎會繼續查詢該變量。直至最外層(全局做用域)。若是引擎找到變量number,就將1這個值賦給number,反之引擎會拋出一個異常。spa

詳情完整的JavaScript的代碼運行機制,請看這裏code

\color{red}{引擎執行怎麼樣的查找,}\color{red}{在咱們的例子中,引擎會爲變量number進行LHS查詢,與之相對的就是RHS查詢。}

2、LHS查詢&RHS查詢

正常的猜測"L"、"R"就是左邊和右邊,賦值操做的左邊和右邊,根據這個猜測,當變量出如今賦值操做的左側是進行LHS查詢,當再出現賦值操做的右邊進行RHS查詢。對象

console.log(number);
複製代碼

這段代碼對number的引用是一個RHS查詢,這裏number沒有賦值任何值,(可能你會說,兄弟你這一行代碼會報錯,沒有聲明變量number,很差意思,打擾了舉着栗子。)ip

number = 1;
複製代碼

這裏對number是一個LHS查詢,引擎並不關心當前賦值的值是什麼,只是想爲 = 1 找到一個目標。作用域

LHS查詢和RHS查詢的含義是"賦值操做的左側和右側",並不必定是意味着是" = 賦值操做符的左側和右側"。賦值操做還有其餘幾種形式,所以在概念上最好將其理解爲"賦值操做的目標是誰(LHS)"以及"誰是賦值操做的源頭(RHS)"。 ----------摘抄《你不知道JavaScript上卷》

function func(number) {
    console.log(number);
}
func(1);
複製代碼

上面的代碼既有LHR查詢也有RHS查詢,咱們一塊兒來分析一下。

  1. 運行func()函數時,對func進行了RHS查詢,查詢func操做的源頭。
  2. 隱藏的聲明number = 1,這裏是將1傳給函數func,1被分配賦值給number,查詢操做的目標是誰,進行一次LHS查詢。
  3. console.log須要一個查詢才能執行,先會對console,進行一個RHS查詢,並檢查console對象是否有一個log的方法。
  4. 而後會對number進行一個RHS查詢。
  5. 最後在console.log()輸出number的值。

看似簡單的一段代碼執行,其中進行了不少的LHR查詢和RHS查詢,這就是引擎須要重複操做的動做。

3、小測試

function foo(a) {
    var b = a;
    console.log(a);
    console.log(b);
    return a + b; 
}

var c = foo(2);
複製代碼
  1. 找出其中全部LHS查詢。
  2. 找出其中全部RHS查詢。

參考【《你不知道JavaScript上卷》】

相關文章
相關標籤/搜索