是LHS查询还是RHS查询?编译器有话说
注:这段是编者在编写完正文之后的重要补充。如果不明白可看完正文返回看这个例子。
关于区别LHS和RHS,我突然想到之前看到的一个比喻:就好比你要给钱给某人,找不到那个人,你就把钱还给他兄弟了(创建一个还钱对象),毕竟不深究的话也是可以的,这就是LHS。但是如果你是追债,那必须要找到欠你钱的那个人,不可能叫别人替他还钱呀,这就是RHS,如果找不到那就只能报警,抛出异常。
在讲解两种查找类型之前,让我们先来简单看看编译原理(了解可跳过)
编译原理
接下来我用 var a = 2; 这个程序来举例分析:
在分词过程会将由字符组成的字符串分解成词法单元,如:var、a、=、2、;
这个过程会将词法单元流转换成抽象语法树AST(一个由元素逐级嵌套所组成的代表了程序语法结构的树)上述大概就是这样的:
代码生成会将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查找:
- c=… ,c是赋值操作的目标,所以对c需要LHS查询。
- 隐藏的a=2(隐式变量分配),在调用foo(2)的时候,需要将实参2赋值给形参阿,所以对a需要LHS查询
- b=… ,同1
RHS查找:
- foo(2) ,foo(2)在赋值操作的右边,需要知道foo(2)的值,所以是RHS查询
- =a,a在赋值操作的右边,需要知道a的值,对a进行RHS查询
- 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查询?编译器有话说相关推荐
- LHS查询和RHS查询
变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值 LHS 当变量出现在赋值操作的左侧时 试图找 ...
- 什么是LHS查询和RHS查询
目录 一.概念 二.例子 三.练习题 一.概念 "L"和"R"分别代表左侧和右侧.那么是什么东西的左侧和右侧呢?是一个赋值操作的左侧和右侧.换句话说,当变量出现 ...
- LHS 查询和 RHS 查询
作用域是一套规则,用于确定在何处以及如何查找变量(标识符).如果查找的目的是对 变量进行赋值,那么就会使用 LHS 查询:如果目的是获取变量的值,就会使用 RHS 查询.
- 作用域中LHS查询和RHS查询
LHS查询:赋值操作左侧的查询,LHS查询试图找到变量的容器本身,,从而对其赋值. RHS查询:赋值操作右侧的查询,可以理解为"取到某某的值" 举例: function foo(a ...
- JavaScript中的LHS和RHS查询
文章是本人大三期间的学习笔记,一些论断取自书籍和网上博客,碍于当时的技术水平有一些写得不够好的地方,可以在评论处理智讨论~ 问题来源于<你不知道的JavaScript(上卷)>,文章部分论 ...
- LHS与RHS查询(已完结)
LHS与RHS查询 什么是LHS与RHS查询 如果查找的目的是对变量进行赋值,那么就会使用LHS 查询:如果目的是获取变量的值,就会使用RHS 查询 考虑以下代码: console.log(a); 其 ...
- Laravel Database——查询构造器与语法编译器源码分析 (上)
前言 在前两个文章中,我们分析了数据库的连接启动与数据库底层 CRUD 的原理,底层数据库服务支持原生 sql 的运行.本文以 mysql 为例,向大家讲述支持 Fluent 的查询构造器 query ...
- [JAVA EE] JPA 查询用法:自定义查询,分页查询
项目已上传:https://codechina.csdn.net/qq_36286039/javaee 自定义查询 问题:内置的crud功能不满足需求时如何添加自定义查询? 几种自定义查询方法 方法命 ...
- MySQL 学习笔记(4)— 组合查询、子查询、插入数据、更新/删除表数据、增加/删除表中的列以及重命名表
1. 组合查询 1.表的加减法 表的加法,即求 product 和 product2 的并集,UNION 运算会除去重复的记录 SELECT product_id, product_name FROM ...
最新文章
- 未来黑客入侵的不仅有电脑,还有人脑?
- hive向mysql导数据_导入Hive数据导MySQL
- androidsettitle方法_在Android应用程序中,Toolbar.setTitle方法无效-应用程序名称显示为标题...
- 《Python Cookbook 3rd》笔记(5.7):读写压缩文件
- 菜鸟学前端--javascript基础
- Server Host Cannot be null解决方法
- java 和mysql 时间_java和mysql之间的时间日期类型传递
- jquery生成二维码图片
- Thymeleaf 的使用
- G4L---linux系统---硬盘对拷(克隆)
- 计算机应用基础课件教学大赛,全国“XX杯”说课大赛计算机应用基础类优秀作品:设置IP地址教学课件.ppt...
- 计算24点有什么窍门或技巧吗?
- linux 硬件raid 坏道,Linux服务器磁盘坏道的修复过程
- 不同数据类型混合运算及类型转换
- 计算机控制分离性原理是什么,分离原理
- 【“工业大数据预测”系列】——第1篇:谈谈工业大数据
- 小白学SLAM的流水账(一):跑通ORB踩过的坑
- 2.6 springBoot学习笔记(2.6)——- 整合mybatisPlus
- java中laber字体颜色设置,QLabel:设置文本和背景的颜色
- 2021-05-03Wireshark流量包分析
热门文章
- DIY显示器篇------DIY教程
- excel 实现身份证号倒数第二位是奇数的显示男,偶数的显示女
- 微信现金红包签名失败问题
- 三维电子沙盘虚拟数字沙盘开发教程第28课
- 微信小程序 - rpx和px互转,以及系统给的 pixelRatio 值比例不对
- python线性拟合模型_Python机器学习-线性回归模型篇
- 【Oralce】导出所有表名、表注释、主键
- error: C2664: “ 无法将参数 1 从“QMap<int,MyData>”转换为“QMap<int,从“QMap<int,MyData>”转>”
- Flutter 布局篇 Positioned 和 Container
- mySQL首行缩进快捷键_首行缩进怎么设置