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上卷》】

相关文章
相关标签/搜索