Rec03|JavaScript 作用域

一、前言

先说编译原理,很多编程语言都要经过3个阶段编程机器码
1、词法分析
var a=2;
依次检查每个词语,看看是否符合规范,上述例子有5个词语
2、语法分析
将词语当做树来存储,如果存储树的结构符合某种规范,那么就判定为正确语法
3、机器码生成
把这些树结构的语句转成机器码,甚至经过优化

在理解作用域之前,先说说JavaScript引擎、编译器:
比如,var a=2;
看上去是一个定义值为2的变量,但涉及到了引擎、编译器与作用域协作。因为,编译器和引擎在做出决策前都要询问作用域。
一方面,编译器在遇到上述句子时,先询问作用域是否有个a变量,若有则忽略这个a的声明,若没有,则到作用域里面声明一个a。
二方面,引擎在运行机器码时候,会先询问作用域是否有a存在,若有,引擎就使用a变量 ,反之引擎抛出异常

进一步说明,引擎如何在作用域查找a呢?
有两种查找机制,LHS和RHS,也就是左右查找,变量出现在那边,就在那边查找。
但是,请注意左右查找的区别,RHS只是返回变量的值,不含赋值才做;而LHS返回的是变量的内存地址,可以赋值

比如,console.log(a)、a=2这两个语句,前者是对a的RHS引用,只查找a的值,传给console;后者则是,含有赋值的LHS引用。
注意:function foo(a)
{
console.log(a);
}
foo(2);
其中包含了2调RHS引用和一条LHS引用,为什么?
调用foo()函数是一次RHS,函数传递参数时是一次a=2的LHS

二。作用域

跟C/C++作用域概念差不多,函数局部的作用域找不到变量后,往外层的全局找。
注意区分LHS和RHS的区别,当使用他们去查找一个不存在的变量时,会产生不同结果,比如

var a = b;
b=2;

前者出现RHS的ReferenceError,后者在非严格模式下正常运行,因为自动创建b变量,但在严格模式下的后者,则也会报ReferenceError.

最后,全局的作用域比较特殊,因为全局的作用域是关乎OS的全局,因此,在Windows系统中,全局存在一个window对象,在全局中的变量会变为全局对象,可用window.a访问

猜你喜欢

转载自blog.csdn.net/weixin_42557786/article/details/112123077