从LHS与RHS角度浅谈Js变量声明与赋值
发布于 8 年前 作者 MrErHu 3786 次浏览 来自 分享

LHS和RHS的概念也是最近从《你不知道的JavaScript》学习到的,LHS是指Left-hand Side,而RHS是指Right-hand Side。二者区别就是关于作用域对变量的查询目的是变量赋值还是查询。   LHS也就是可以理解为变量在赋值操作符(=)的左侧,例如 a = 1,当前引擎对变量a查找的目的是变量赋值。   RHS可以理解为变量在赋值操作符(=)的右侧,例如:var b = a,其中引擎对变量a的查找目的就是查询。   那么对于下面一个简单的语句:

var a = 1;

对于上述语句,可以分解成一下两步:

var a;
a=1

首先第一步执行LHS,引擎通知词法作用域,查询对应的作用域中是否存在该变量a,词法作用域发现当前作用域中不存在变量a,则在当前作用域中声明变量a;然后第二步执行RHS,对查询到的变量a进行赋值。 在举一个例子:

function fn(a){
    console.log(a+b);
    b=a;
}
fn(2);

编译器对console.log()中的b执行的是RHS查询,如果查询不到的话,会抛出ReferenceError的错误。如果在执行LHS中查询不到对应的变量,在非严格模式下会创建变量并且进行赋值,如果在执行RHS查询的过程中,对查询到的变量操作不正确,例如对非函数(undefined,null)执行函数操作时,会报出TypeError的错误。这样就合理的解释了下面的例子

(function(){
    a=100;
})();
console.log(a);//100

之前的理解是如果不对变量a采用var声明的时候,自动创建的是全局变量,其实现在我们就可以合理的解释,首先a=100对变量a执行的是LHS查询,当前作用域中不存在a,会一直向上查找,直到全局作用范围中仍然无法找到该变量,因为是在非严格模式下(严格模式会直接报ReferenceError的错误),所以编译器会自动在全局范围中创建变量a,并赋值100,这样我们所观察到的结果就是在全局范围中创建了变量a。   欢迎访问我的个人博客,https://mrerhu.github.io,入行资历甚浅,不吝赐教。

回到顶部