对代码进行处理的三个角色
引擎:从头到尾负责整个 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 处
这里每一次查找,都需要跟作用域配合一次
原文地址:https://www.cnblogs.com/wzndkj/p/12297855.html
时间: 2024-10-12 09:04:24