你不知道的JS系列- 引擎怎么查找变量

Posted Zina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你不知道的JS系列- 引擎怎么查找变量相关的知识,希望对你有一定的参考价值。

对代码进行处理的三个角色
引擎:从头到尾负责整个 javascript 程序的编译和执行过程
编译器:负责语法分析及代码生成等
作用域:负责收集并维护所有变量的查询

 

var a = 2;
编译器首先会将这段程序分解成词法单元,然后将词法单元流解析成一个树结构。然后将树结构转换成可执行代码,也就是计算机懂的指令。为一个变量分配内存,将其命名为 a,然后将值 2 保存进这个变量。这符合编译原理

 

然而并不完全正确

 

事实上编译器会进行如下处理
1、在词法分析中,遇到 var a,编译器会询问当前作用域是否有该变量。是,忽略该变量继续编译。否,要求作用域声明一个新的变量
2、在生成代码中,编译器对 a = 2 进行赋值操作。首先询问作用域,在当前作用域是否存在该变量。是,使用该变量。否,引擎继续查找该变量

如果引擎找到了 a ,就将 2 赋值给它。否则抛出异常

变量赋值操作会执行两个动作,一个是编译器在当前作用域声明该变量,然后引擎在作用域中查找该变量,进行赋值

 

查找的过程由作用域进行协助,但是引擎执行怎么样的查找,会影响最终的查找结果。引擎会为变量 a 进行 LHS 查询。另外一个查找的类型叫做 RHS 。它们代表赋值操作的左侧和右侧。更准确的说,LHS 查询是试图找到变量的容器本身。

 

LHS 和 RHS 的含义是 “赋值操作的左侧或右侧”,并不一定意味着就是 “ = 赋值操作符的左侧或右侧”。赋值操作还有其他几种形式,因此在概念上最好将其理解为 “赋值操作的目标是谁(LHS)” 以及 “谁是赋值操作的源头(RHS)”。

 

比如
function foo(a) {
  console.log(a) //2
}
foo(2);
对 foo 进行 RHS 引用。对 a 进行 LHS 引用。对 console 进行 RHS 引用

 

function foo(a){
  var b = a;
  return a + b;
}
var c = foo(2);
这里 LHS 有 3 处,RHS 有 4 处
 
这里每一次查找,都需要跟作用域配合一次
 

 

以上是关于你不知道的JS系列- 引擎怎么查找变量的主要内容,如果未能解决你的问题,请参考以下文章

你不知道的JavaScript学习笔记1——作用域

你不知道的js

你不知道的JS系列 ( 5 ) - 词法作用域

JS你不知道的JavaScript 笔记—— 作用域与闭包 - 编译原理 - LHS - RHS - 循环与闭包 - 模块 - 词法作用域 - 动态作用域

js中的词法作用域

js中的词法作用域