注:这段是编者在编写完正文之后的重要补充。如果不明白可看完正文返回看这个例子。
关于区别LHS和RHS,我突然想到之前看到的一个比喻:就好比你要给钱给某人,找不到那个人,你就把钱还给他兄弟了(创建一个还钱对象),毕竟不深究的话也是可以的,这就是LHS。但是如果你是追债,那必须要找到欠你钱的那个人,不可能叫别人替他还钱呀,这就是RHS,如果找不到那就只能报警,抛出异常。

在讲解两种查找类型之前,让我们先来简单看看编译原理(了解可跳过)

编译原理

接下来我用 var a = 2; 这个程序来举例分析:

  1. 在分词过程会将由字符组成的字符串分解成词法单元,如:var、a、=、2、;

  2. 这个过程会将词法单元流转换成抽象语法树AST(一个由元素逐级嵌套所组成的代表了程序语法结构的树)上述大概就是这样的:

  3. 代码生成会将AST转换为可执行的代码。简单来说就是有某种方法可以将var a=2;的AST转化为一组机器指令,用来创建一个叫a的变量(包括分配内存等),并将一个值存储在a中。

编译器在编译过程生成了代码,引擎执行它时,会通过查找变量a来判断它是否已经声明过。查找的类型就是我们将要讨论的两种:LHS查询和RHS查询。查找的过程需要作用域的协助,但是引擎执行查找的方式会影响最终的查找结果。

LHS 和 RHS

LHS(left-hand Side)引用和RHS(right-hand Side)引用,通常是指等号(赋值运算)的左右边的引用。

举例说明:

console.log(a);

这里对a的引用是一个RHS引用,因为这里a并没有赋予任何值,由于我们只是想查找并取得a的值然后打印。

a = 2;

这里对a的引用是一个LHS引用,我们并不关心当前的值是什么,只是想要为赋值操作找到目标。

通过这两个例子我们也能看出,LHS和RHS的含义是“赋值操作的左侧和右侧”并不一定意味这就是"="的左侧和右侧。赋值操作还有其他几种形式,因此在概念上最好将其理解为“赋值操作的目标是谁(LHS)”以及“谁是赋值操作的源头(RHS)”。

我再将小黄书上的那道例题解析一下,帮助大家理解

function foo(a) {var b = a;return a + b;
}var c = foo(2);

先告诉大家答案,这里一个有3个LHS查询和4个RHS查询。你们可以停顿一会儿,自己找找,也可以继续往下看。

LHS查找:

  1. c=… ,c是赋值操作的目标,所以对c需要LHS查询。
  2. 隐藏的a=2(隐式变量分配),在调用foo(2)的时候,需要将实参2赋值给形参阿,所以对a需要LHS查询
  3. b=… ,同1

RHS查找:

  1. foo(2) ,foo(2)在赋值操作的右边,需要知道foo(2)的值,所以是RHS查询
  2. =a,a在赋值操作的右边,需要知道a的值,对a进行RHS查询
  3. a…,在return a+b中,需要知道a和b的值,应该对a和b分别进行RHS查询。

注:通过实例我们可以发现,如果查找的目的是对变量进行赋值,那么就会使用LHS查询;如果目的是获取变量的值,就会使用RHS查询

为什么要区分LHS 和 RHS

因为在变量还没有声明(在任何作用域中都无法找到该变量)的情况下,这两种查询的行为是不一样的 。

当对一个变量执行RHS查询时,如果遍历该变量所在处的词法作用域未能找到这个变量,JS引擎就会抛出 ReferenceError 错误。如果成功查询到了这个变量,但是对这个变量执行不合理操作,比如对一个非函数类型的值进行函数调用,或者引用null或undefined类型中的值中的属性,JS引擎就会抛出 TypeError 错误。

当对一个变量执行LHS查询时,同样在遍历作用域后无法找到该变量,在非ES5的严格模式下,系统就会自动在全局作用域中创建一个同名变量。而在ES5的严格模式下,LHS查询失败时JS引擎会抛出一个同RHS一样的 ReferenceError 错误。

是LHS查询还是RHS查询?编译器有话说相关推荐

  1. LHS查询和RHS查询

    变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值 LHS 当变量出现在赋值操作的左侧时 试图找 ...

  2. 什么是LHS查询和RHS查询

    目录 一.概念 二.例子 三.练习题 一.概念 "L"和"R"分别代表左侧和右侧.那么是什么东西的左侧和右侧呢?是一个赋值操作的左侧和右侧.换句话说,当变量出现 ...

  3. LHS 查询和 RHS 查询

    作用域是一套规则,用于确定在何处以及如何查找变量(标识符).如果查找的目的是对 变量进行赋值,那么就会使用 LHS 查询:如果目的是获取变量的值,就会使用 RHS 查询.

  4. 作用域中LHS查询和RHS查询

    LHS查询:赋值操作左侧的查询,LHS查询试图找到变量的容器本身,,从而对其赋值. RHS查询:赋值操作右侧的查询,可以理解为"取到某某的值" 举例: function foo(a ...

  5. JavaScript中的LHS和RHS查询

    文章是本人大三期间的学习笔记,一些论断取自书籍和网上博客,碍于当时的技术水平有一些写得不够好的地方,可以在评论处理智讨论~ 问题来源于<你不知道的JavaScript(上卷)>,文章部分论 ...

  6. LHS与RHS查询(已完结)

    LHS与RHS查询 什么是LHS与RHS查询 如果查找的目的是对变量进行赋值,那么就会使用LHS 查询:如果目的是获取变量的值,就会使用RHS 查询 考虑以下代码: console.log(a); 其 ...

  7. Laravel Database——查询构造器与语法编译器源码分析 (上)

    前言 在前两个文章中,我们分析了数据库的连接启动与数据库底层 CRUD 的原理,底层数据库服务支持原生 sql 的运行.本文以 mysql 为例,向大家讲述支持 Fluent 的查询构造器 query ...

  8. [JAVA EE] JPA 查询用法:自定义查询,分页查询

    项目已上传:https://codechina.csdn.net/qq_36286039/javaee 自定义查询 问题:内置的crud功能不满足需求时如何添加自定义查询? 几种自定义查询方法 方法命 ...

  9. MySQL 学习笔记(4)— 组合查询、子查询、插入数据、更新/删除表数据、增加/删除表中的列以及重命名表

    1. 组合查询 1.表的加减法 表的加法,即求 product 和 product2 的并集,UNION 运算会除去重复的记录 SELECT product_id, product_name FROM ...

最新文章

  1. 未来黑客入侵的不仅有电脑,还有人脑?
  2. hive向mysql导数据_导入Hive数据导MySQL
  3. androidsettitle方法_在Android应用程序中,Toolbar.setTitle方法无效-应用程序名称显示为标题...
  4. 《Python Cookbook 3rd》笔记(5.7):读写压缩文件
  5. 菜鸟学前端--javascript基础
  6. Server Host Cannot be null解决方法
  7. java 和mysql 时间_java和mysql之间的时间日期类型传递
  8. jquery生成二维码图片
  9. Thymeleaf 的使用
  10. G4L---linux系统---硬盘对拷(克隆)
  11. 计算机应用基础课件教学大赛,全国“XX杯”说课大赛计算机应用基础类优秀作品:设置IP地址教学课件.ppt...
  12. 计算24点有什么窍门或技巧吗?
  13. linux 硬件raid 坏道,Linux服务器磁盘坏道的修复过程
  14. 不同数据类型混合运算及类型转换
  15. 计算机控制分离性原理是什么,分离原理
  16. 【“工业大数据预测”系列】——第1篇:谈谈工业大数据
  17. 小白学SLAM的流水账(一):跑通ORB踩过的坑
  18. 2.6 springBoot学习笔记(2.6)——- 整合mybatisPlus
  19. java中laber字体颜色设置,QLabel:设置文本和背景的颜色
  20. 2021-05-03Wireshark流量包分析

热门文章

  1. DIY显示器篇------DIY教程
  2. excel 实现身份证号倒数第二位是奇数的显示男,偶数的显示女
  3. 微信现金红包签名失败问题
  4. 三维电子沙盘虚拟数字沙盘开发教程第28课
  5. 微信小程序 - rpx和px互转,以及系统给的 pixelRatio 值比例不对
  6. python线性拟合模型_Python机器学习-线性回归模型篇
  7. 【Oralce】导出所有表名、表注释、主键
  8. error: C2664: “ 无法将参数 1 从“QMap<int,MyData>”转换为“QMap<int,从“QMap<int,MyData>”转>”
  9. Flutter 布局篇 Positioned 和 Container
  10. mySQL首行缩进快捷键_首行缩进怎么设置