最近在学习javascript过程当中,接触了LHS与RHS的概念,刚开始的时候有点理解不清,如今作一些梳理,方便之后进行理解。javascript
LHS与RHS:javascript引擎的两种查找类型,含义是赋值操做的左侧与右侧。html
LHS:对哪一个赋值就对哪一个进行LHS引用,能够理解为赋值操做的目标。java
RHS:须要获取哪一个变量的值,就对哪一个变量的值进行RHS引用,理解为赋值操做的源头。函数
赋值操做有多种形式,对于以上的两种对LHS与RHS的解释,我刚刚接触,仍是很混乱。学习
个人理解就是,通常在左边的须要被赋值,就是LHS引用,右边须要寻找到他的值,就是RHS引用。spa
例如:code
1 function foo(a){ 2 var b=a; 3 rerurn a+b; 4 } 5 var c=foo(2);
以上代码中有3个LHS与4个RHS,分析以下:htm
第一,var c中的c须要被赋值,在赋值操做的左侧,因此对c进行LHS引用blog
第二,变量c须要被赋值,他的值是foo(2),那么foo(2)的值是多少呢,须要查找foo(2)的值,在赋值操做的右侧,因此对foo(2)进行RHS引用ip
第三,隐含赋值操做,将2传递给function foo(a){……}函数的参数a,a在赋值操做的左侧,对a进行LHS引用
第四,var b=a;中,b须要被赋值,处在赋值操做的左侧,因此b进行的LHS,b的值将从a来,那么右侧的a的值从何而来呢?这就须要对赋值操做右侧的a进行RHS。
第五,return a+b;中,须要找到a与b的值的来源,a与b都在赋值操做的右侧,才能获得a+b的值,因此对a与b都是进行RHS引用。
为何要区分LHS与RHS?
由于在变量尚未声明(在任何做用域中都没法找到该变量)状况下,这两种查询行为是不同的。
例如:
1 function foo(a){ 2 console.log(a+b); 3 b=a; 4 } 5 foo(2);
以上代码对b进行RHS的时候没法找到该变量的值,则会抛出ReferenceError异常,若是是LHS找不到变量,非严格模式下,会在全局做用域中,建立一个具备该名称的变量,严格模式下,会抛出与RHS相似的异常。
例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript"> function init(a){ b=a+3; } init(2); alert(b);//5 </script> </head> <body> </body> </html>
以上代码中,对b进行LHS没有找到该变量,在全局做用域中建立了一个同名的变量b,在函数init外部能够访问到b变量。
若是将代码更改成以下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script type="text/javascript"> 7 function init(a){ 8 var b=a+3; 9 10 } 11 init(2); 12 alert(b); 13 </script> 14 </head> 15 <body> 16 17 </body> 18 </html>
在function中定义了一个局部变量b,全局做用域中定义,控制台报错如图显示,窗口中没有任何输出
将代码改为以下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script type="text/javascript"> 7 function init(a){ 8 var b=a+3; 9 10 } 11 init(2); 12 alert(window.b);//undefined 13 </script> 14 </head> 15 <body> 16 17 </body> 18 </html>
将代码改为如上所示,控制台并无报错, 由于window.b做为window的一个属性访问,因此会返回undefined,而b做为一个变量没有定义的时候是会报错的