LHS和RHS深入理解javascript引擎与作用域的交互

简介: LHS和RHS深入理解javascript引擎与作用域的交互

前言

      几乎所有编程语言最基本的功能之一,就是能够储存变量当中的值,并且能在之后对这个值进行访问或修改。事实上,正是这种储存和访问变量的值的能力将状态带给了程序。一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量。这套规则被称为作用域。

      对于javascript而言,与传统编译语言不同,我们常称它为“动态解释性“语言,因为它不是提前编译,它的编译过程中引擎在对变量值进行操作的时候会与作用域之间进行沟通交互,其中有两个非常重要的过程LHS和RHS,后面我们将围绕这两个过程深入理解javascript引擎与作用域的交互

正文

      编译器在编译过程中生成了代码,引擎执行它时,会通过查找变量来判断它是否已声明过。查找的过程由作用域进行协助,但是引擎执行怎样的查找,会影响最终的查找结果。而作用域查询的类型分为两种, LHS和RHS

LHS

      我打赌你一定能猜到“L”和“R”的含义,它们分别代表左侧和右侧。什么东西的左侧和右侧?是一个赋值操作的左侧和右侧。

      比如var a = 3;的代码,引擎执行a的过程就是LHS,LHS 查询则是试图找到变量的容器本身,从而可以对其赋值。是一个赋值的过程

RHS

      与LHS对应的是RHS,你可以将 RHS 理解成 retrieve his source value(取到它的源值),这意味着“得到某某的值”。比起右边,可能非左边能更好地描述RHS,举个例子:

640.png

      像上面这个例子没有=,其中对 a 的引用是一个 RHS 引用,因为这里 a 并没有赋予任何值。相应地,需要查找并取得 a 的值,这样才能将值传递给console.log(…)。

看个例子加深一下印象

      光说概念,同学们可以不一定能理解透彻LHS和RHS,对于下面的例子,我们假设自己是引擎,在与作用域沟通的过程中,分别有几次LHS和RHS呢

      三次LHS,四次RHS,同学们答对了嘛

      先说一下LHS,LHS是赋值,b= 和c =我们不难找到,那么还有一处在哪里呢,还有一处隐式调用,foo(2)处其实有a = 2的隐式赋值,也属于LHS查询。

      然后我们再分析一下RHS, RHS是取值,这个很简单,=a, a, b, foo(2)四处,并不难

作用域嵌套

      我们说过,作用域是根据名称查找变量的一套规则。实际情况中,通常需要同时顾及几个作用域。

      当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。

      遍历嵌套作用域链的规则很简单:引擎从当前的执行作用域开始查找变量,如果找不到,就向上一级继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都会停止。

为什么要区分LHS和RHS

      因为在ES5中,LHS和RHS在没找到变量时的反应是不同的,如果 RHS 查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError异常。值得注意的是,ReferenceError 是非常重要的异常类型。相较之下,当引擎执行 LHS 查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎。

      如果是严格模式或者ES6环境下,将禁止自动或隐式地创建全局变量。因此,在严格模式中 LHS 查询失败时,并不会创建并返回一个全局变量,引擎会抛出同 RHS 查询失败时类似的 ReferenceError 异常。

小结

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

目录
相关文章
|
2月前
|
开发框架 JavaScript 前端开发
揭秘:如何让你的asp.net页面变身交互魔术师——先施展JavaScript咒语,再引发服务器端魔法!
【8月更文挑战第16天】在ASP.NET开发中,处理客户端与服务器交互时,常需先执行客户端验证再提交数据。传统上使用ASP.NET Button控件直接触发服务器事件,但难以插入客户端逻辑。本文对比此法与改进方案:利用HTML按钮及JavaScript手动控制表单提交。后者通过`onclick`事件调用JavaScript函数`SubmitForm()`来检查输入并决定是否提交,增强了灵活性和用户体验,同时确保了服务器端逻辑的执行。
40 5
|
2月前
|
JavaScript 前端开发
浅谈js作用域
浅谈js作用域
28 0
|
9天前
|
JavaScript 前端开发
js 变量作用域与解构赋值| 22
js 变量作用域与解构赋值| 22
|
8天前
|
缓存 JavaScript 前端开发
了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化
该文章详细讲解了JavaScript中的作用域、闭包概念及其应用场景,并简要分析了函数柯里化的使用。
了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化
|
1月前
|
JavaScript 前端开发
JavaScript基础知识-作用域(action scope)
关于JavaScript基础知识中作用域的介绍。
26 1
JavaScript基础知识-作用域(action scope)
|
1月前
|
JavaScript 前端开发
JavaScript 作用域
JavaScript 作用域
23 9
|
1月前
|
JavaScript 前端开发
JavaScript 与 DOM 交互
【9月更文挑战第01天】
22 2
|
2月前
|
JavaScript 前端开发
使用 let 将有助于避免 JavaScript 中各种 var 引起的作用域问题。
这段内容介绍了JavaScript编程时的一系列最佳实践,包括使用`===`而非`==`进行比较、以`let`和`const`取代`var`定义变量、始终使用分号、采用合适的命名规范、利用模板字符串拼接、偏好ES6箭头函数、在控制结构中使用大括号、减少代码嵌套、应用默认参数、正确使用`switch`语句中的`break`与`default`分支、避免通配符导入以及简化布尔判断和避免不必要的三元运算符。遵循这些规则有助于提升代码的清晰度和可维护性。
16 2
|
2月前
|
JavaScript 前端开发 UED
Vue.js动画魔法:解锁流畅过渡,让每一次交互都成为用户心中的小确幸!
【8月更文挑战第30天】在Vue.js中,动画与过渡效果不仅是视觉点缀,更是提升用户体验的关键。通过流畅的动态效果,应用的互动性和吸引力得以增强,从而提高用户满意度和参与度。`<transition>`和`<transition-group>`组件结合CSS过渡,可轻松实现元素的进入、离开及列表变化动画。合理的性能优化,如使用硬件加速,能避免页面卡顿,确保动画既美观又高效。下面是一个简单的淡入淡出效果示例,展示了如何利用Vue.js实现平滑的动画过渡。总之,恰当的动画设计能显著提升应用的用户体验。
41 0
Vue.js动画魔法:解锁流畅过渡,让每一次交互都成为用户心中的小确幸!
|
2月前
|
JavaScript 前端开发
JavaScript基础&实战(4)js中的对象、函数、全局作用域和局部作用域
这篇文章介绍了JavaScript中对象的基本概念和操作,包括对象属性和方法的使用、对象字面量的创建、函数的定义和作用域的概念,以及全局作用域和局部作用域的区别和特性。
JavaScript基础&实战(4)js中的对象、函数、全局作用域和局部作用域