定义变量的过程

const a=2
定义变量的这个过程中,具体会发生什么,能否给个详细的过程说明,网上没查到资料

阅读 2.3k
3 个回答

楼上给的链接写的还是有点简单了,在这做个补充:

  1. 编译器第一件做的事叫 词法分析和语义分析:把这一句代码分解成词法单元,然后将其解析,成为一个语法树(这点可以看编译原理,不再深究)
  2. 编译期:创建Activation Object(执行期上下文),编译器查询该作用域是否有同名变量 a,如果有,忽略该声明,继续编译,如果没有,则声明一个新变量,命名为a,值为undefined。
  3. 执行期:编译器会为引擎生成运行时所需的代码,用来处理 a = 2 这个操作。首先进行LHS查询,查询在当前作用域是否存在一个叫a的变量,如果有,把2这个值赋给它,如果没有,抛出一个异常。
什么是 LHS 查询 和 RHS 查询:

一段代码以蔽之:

var a = 2; // a 是赋值操作的目标 => 进行LHS查询
var b = a; // b 是赋值操作的目标,a 是赋值操作的源头,对b进行赋值操作 => LHS查询,查找变量 a => RHS查询

LHS 和 RHS 查询都会在当前执行作用域中开始,如果没有找到标识符,那就沿着作用域链向上查找,最后抵达全局作用域后停止。

ReferenceError 和 TypeError 异常:
  • RHS 查询不成功会抛出一个 ReferenceError 异常
  • 如果RHS查询成功,但是你对这个变量进行一些非法操作,那会抛出 TpyeError 异常
  • 不成功的 LHS 查询会自动隐式的创建一个全局变量(非严格模式),该变量使用LHS引用的目标作为标识符,或者抛出ReferenceError异常(严格模式下)。

总个结:变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量a(LHS查询),如果能够找到就会对它赋值。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

const a=2;
其实就是运行解释器在内存中找个地方存放了值2这个常量,然后分配了一个标记a指向这个内存。这样一来,以后使用a就会使用到这个值,而且这个值因为放置并且标记了不可更改(是常量),所以不能再给a赋值。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题