【JS】RHS和LHS查找

JS中关于查询,分为左查询(LHS)、右查询(RHS)。
LHS:找到某个变量的值,如果查找的目的是对变量进行赋值,就会使用LHS查找。
RHS:找到变量的容器,如果查找的目的是获取变量的值,就会使用RHS查找。
可简单理解赋值操作为执行LHS,取值/引用操作为RHS。

LHS

var a = 2; 为例,我们分析JavaScript的LHS查询过程,我们把声明和赋值分开看:

首先是 var a:

  1. 查询当前作用域是否有变量a;
  2. 如果没有,就在当前作用域声明一个;
  3. 如果有,就忽略该声明,继续往下执行。

其次是a = 2; 「执行LHS

  1. 查询当前作用域是否有变量a;
  2. 如果没有,就往上一级作用域查找,直到全局作用域为止;
    非严格模式下:全局作用域没找到,就在全局作用域声明一个变量a;
    严格模式下,会出现ReferenceError;
  3. 如果有,进行赋值操作。

RHS

console.log(a); 为例,我们分析RHS查询过程:

  1. 查询当前作用域是否有变量a;
  2. 如果有,引用标识符a对应的值(只有声明的话为值undefined);
  3. 如果没有,会出现ReferenceError。

案例

一、

function foo(a){
    
    
	console.log(a)
}
foo(2) // 2

对foo函数的调用执行了RHS查找,还有一个隐式的 a=2 的操作,这是赋值操作,所以执行了LHS查找。

二、

 function foo(a){
    
    
   console.log(a+b)
 }
 foo() // Uncaught ReferenceError: b is not defined

如果RHS在作用域链中找不到需要的变量,就会抛出异常:ReferenceError。
  
  
三、

function foo(a) {
    
    
  b = a
  console.log(b)
}
foo(2) // 2

b=a就是给b赋值,就是执行了LHS查找。注意,在使用LHS查找的时候,在非严格模式下,js引擎在全局都没有找到b,就会在全局作用域中声明了一个变量b,此时b为undefined,在这里b=a后b的值为2。

严格模式下,RHS查找失败,抛出ReferenceError异常

'use strict'
 function foo(a) {
    
    
   b = a
   console.log(b)
 }
 foo(2) // Uncaught ReferenceError: b is not defined

案例总结:
如果RHS查找失败,就会抛出ReferenceError异常;
如果LHS查找失败,自动在全局创建一个全局变量,当然这是在非严格模式下才会进行创建。

总结

LHS:找到某个变量的值,如果查找的目的是对变量进行赋值,就会使用LHS查找。
RHS:找到变量的容器,如果查找的目的是获取变量的值,就会使用RHS查找。

console.log(a) 这种变量在右可以理解为RHS,它若未在嵌套作用域中找到变量a,则会抛出一个refunserror。
var a=1 这种变量在左可以理解为LHS,在非严格模式下,它若未在嵌套作用域中找到该变量,会在顶级作用域(全局)中创建一个。

拓展

“与 var 关键字不同,使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)” —《JavaScript 高级程序设计》

let a = "a"
console.log(window.a);  // undefined
var b = "b"
console.log(window.b);  // 'b'

猜你喜欢

转载自blog.csdn.net/owo_ovo/article/details/135249412
今日推荐