你不知道的JavaScript LHS 和 RHS 查找

  今天在学习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。

 

posted @ 2019-06-13 11:05 随心小宝 阅读(...) 评论(...) 编辑 收藏