声明变量
例子:在var a = 2
的时候, 参与这段语句的角色都做了什么?
介绍角色:
- 引擎:负责整个JavaScript程序的编译及执行过程。
- 编译器:负责语法分析及代码生成等。
- 作用域:可访问标识符(变量、常理)的区域。
过程:
- 首先,引擎会在当前作用域查看该语句
var a = 2
,视为var a
, ,然后询问作用域是否存在一个该名称的变量存在同一个作用域的集合中,如果有,编译器就忽略该声明,继续编译;否则,就会在当前作用域的一个集合中声明一个新的变量,并命名为“a”。 - 然后到了编译器,会为引擎生成的代码进行运行,如果运行到了
var a = 2
,视为a = 2
,并查找当前作用域的集合中是否有“a”这个变量,如果有,就直接对这个变量a进行赋值,如果没找到,就会抛出异常。
RHS 与 LHS
举个例子:
var a = 2
console.log( a );
在上面的过程中,console.log(a)
进行了RSL操作,这个操作的意思是,会获取变量的值,引擎就会去寻找a的源头,如果没有,就会抛出ReferenceError异常;差不多的是,进行a = 2
这个操作时候,就会进行LHS操作,即去给这个a赋值,如果提前声明变量a,那么就会隐式的去声明一个变量a,并赋值(如果有使用严格模式,就会抛出ReferenceError异常)。
准确点来说,RHS是去寻找变量的源头,引擎会去询问作用域,问当前作用域是否有此变量,如果有,皆大欢喜,如果没有,就向上个作用域问,直到全局作用域也没有为止,到此,就会抛出异常。而LHS,如果对变量进行赋值,就会进行这个操作,即“赋值操作的目标是谁!”