你不知道的javaScript【笔记】— LHS与RHS
引入LHS和RHS
首先,一段js代码在运行之前是要编译(词法分析,语法分析,代码生成)的,编译后得到的目标代码给引擎去执行。怎么编译呢?
例如var a=2; (看似一步,实则两步!两步!!两步!!!)
1)遇到var a,编译器会询问当前作用域是否有a这个变量,如果有就忽略,没有的话就命名一个变量取名为a。
2)接下来编译器为引擎生成目标代码,这些代码用来处理a=2这个赋值操作(很重要哇,目标代码是没有赋值的),然后引擎执行这段目标代码时,询问当前作用域集合中是否有a这个变量(LHS),有的话就赋值,没有的话分情况看查询方法是LHS还是RHS。
所以什么是LHS和RHS?
L,R明显就是左右,LHS查询可以被看成是查找某个变量的容器,也就是那个内存地址。RHS呢,是查找某个变量的值。
LHS:赋值操作,传参(找容器)
RHS:函数调用,变量出现在=的右边(找内容)
参考代码:
function foo(a){
var b=a; //b=a(RHS找a的值,LHS找b的地址)
console.log(a+b); //调用console.log(RHS,传参先分别对a、b RHS,再LHS传参)
}
foo(2); //调用foo(RHS),传参(LHS,隐式a=2)
区分LHS和RHS有什么用?
作用大了哦,
注意联系作用域链,两种都会一直往上查,查到就停,没有就往上查,一直到全局都没有就是下文。
RHS没找的话会抛出异常*ReferenceError* ,是不是很熟悉这个异常类型,没错,就是这么来的。
LHS没找到的话,就会在全局创建创建一个该变量,并把他返回给引擎,注意值是undefined,是否赋值是在上文提到的第二步。
严格模式 :禁止隐式创建全局变量,所以LHS失败也会抛出*ReferenceError*