你不知道的JavaScript LHS 和 RHS 查找

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

    變量的賦值執行兩個動做,函數

    一、編譯器會在當前做用域中申明一個變量(若是以前沒有申明過)。學習

    二、在運行時引擎會在做用域中查找該變量,若是能找到就會對他賦值。spa

  首先咱們要知道JavaScript程序都是經過JavaScript引擎編譯執行來完成的,那咱們首先要知道引擎及他的好朋友編譯器和做用域是什麼對象

  一、引擎:從頭至尾負責整個JavaScript程序的編譯及執行過程。ip

  二、編譯器:引擎的好朋友之一,負責語法分析及代碼生成等髒活累活。作用域

  三、做用域:引擎的另外一位好朋友,負責收集並維護由全部聲明的標識符(變量)組成的一系列查詢,並實施一套很是嚴格的規則,肯定當前執行的代碼對這些標識符的訪問權限。編譯器

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

  編譯器在編譯執行過程的第二步中生成了代碼,引擎執行它時,會經過查找變量來判斷它是否已經聲明過,查找的過程由做用域進行協助,可是引擎執行怎樣的查找,會影響最終的查找結果。所謂的LHS和RHS查找,相信你必定能猜到「L」和「R」表明左側和右側,具體是什麼的左側和右側呢?是賦值操做的左側和右側,但賦值操做不僅僅只是賦值操做符哦。console

  爲了可以完成的理解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。

相關文章
相關標籤/搜索