你不知道的JavaScript LHS 和 RHS 查詢

隨心小寶發表於2019-06-13

  今天在學習JavaScript的相關知識時接觸到了 LHS(Left Hand Side)和 RHS(Right Hand Side)兩種對變數查詢的方法,之所以JavaScript要查詢變數,那就先要了解JavaScript對變數賦值操作的原理:

    變數的賦值執行兩個動作,

    1、編譯器會在當前作用域中申明一個變數(如果之前沒有申明過)。

    2、在執行時引擎會在作用域中查詢該變數,如果能找到就會對他賦值。

  首先我們要知道JavaScript程式都是通過JavaScript引擎編譯執行來完成的,那我們首先要知道引擎及他的好朋友編譯器和作用域是什麼

  1、引擎:從頭到尾負責整個JavaScript程式的編譯及執行過程。

  2、編譯器:引擎的好朋友之一,負責語法分析及程式碼生成等髒活累活。

  3、作用域:引擎的另一位好朋友,負責收集並維護由所有宣告的識別符號(變數)組成的一系列查詢,並實施一套非常嚴格的規則,確定當前執行的程式碼對這些識別符號的訪問許可權。

-------《你不知道的JavaScript 上卷》

  編譯器在編譯執行過程的第二步中生成了程式碼,引擎執行它時,會通過查詢變數來判斷它是否已經宣告過,查詢的過程由作用域進行協助,但是引擎執行怎樣的查詢,會影響最終的查詢結果。所謂的LHS和RHS查詢,相信你一定能猜到“L”和“R”代表左側和右側,具體是什麼的左側和右側呢?是賦值操作的左側和右側,但賦值操作不單單只是賦值操作符哦。

  為了能夠完成的理解JavaScript的工作原理,你需要開始像引擎(和他的朋友們)一樣思考,從它們的角度提出問題,並從他們的角度回答這些問題,我們首先來看一個例子:

  // 程式碼部分 

  function foo(a) {

    console.log( a ); //2

  }

  foo( 2 );


  讓我們把上面這段程式碼的處理過程想象成一段對話,這段對話可能是下面這樣的。

    引擎: 我說作用域, 我需要為 foo 進行 RHS 引用。 你見過它嗎?

    作用域: 別說, 我還真見過, 編譯器那小子剛剛宣告瞭它。 它是一個函式, 給你。

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

    引擎: 作用域, 還有個事兒。 我需要為 進行 LHS 引用, 這個你見過嗎?

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

    引擎: 大恩不言謝, 你總是這麼棒。 現在我要把 賦值給 a

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

    作用域: 我們倆誰跟誰啊, 再說我就是幹這個。 這個我也有, console 是個內建物件。給你。

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

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

    作用域: 放心吧, 這個變數沒有變動過, 拿走, 不謝。

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

-------《你不知道的JavaScript 上卷》

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

  在上面的例子中要注意的是:console.log(..) 本身也需要一個引用才能執行,因此會對console 物件進行RHS 查詢,並且檢查得到的值中是否有一個叫作log 的方法。這裡不會再對log進行RHS查詢。因為對console查詢完畢後,物件屬性訪問規則會接管對log屬性的訪問。也就是說,如果是訪問物件的屬性就不存在LHS查詢和RHS查詢了,找不到就返回undefined。

 

相關文章