JavaScript 引擎在查找一个变量的时候,有两种查找机制:LHS 和 RHS。

RHS 的查询是简单地查找到某个变量的值,而 LHS 则是试图找到变量的容器的本身。

一个简单的例子:当我们执行 console.log(a) 时,执行的就是 RHS ,因为这里 a 并没有赋予任何的值。相应的,需要查找并取得 a 的值,这样才能将值传递给 conso.log(..)。

而当我们执行到 a = 2 时,这里对 a 的引用就是 LHS 引用,因为实际上我们并不关心当前的值是什么,只是想要为 =2 这个赋值操作找到一个目标。

需要注意的是:

当我们执行以下代码:

function foo(a){

  console.log(a);  // 2

}

foo(2);

这里对 foo 的调用执行了 RHS 引用,但还有一个隐式的 a = 2 的操作,这里又执行了一个 LHS 引用。

我们通常把 function foo(a){} 转变为 var foo,foo = function(){} ,如果这样理解的话,这个函数声明会执行 LHS 查询,但是在引擎执行代码的时候,并不会有线程专门用来将一个函数值“分配给”foo。所以,将函数声明理解成 赋值 的 LHS 查询的形式并不合适。

区分 LHS 和 RHS 是一件很重要的事。如果 RHS 查询在作用域链中找不到需要的变量,会抛出 ReferenceError 的异常。

function foo(a){

  console.log(a + b);

}

foo()

以上代码会抛出异常:b is not defined

相比之下,如果JavaScript引擎执行的是 LHS 查询,如果一直到顶层的作用域(全局作用域)中都没有找到目标变量的话,它就会在全局作用域中声明一个具有目标名称的变量,并将其返回给引擎。(非严格模式下,严格模式下会禁止自动创建或隐式创建全局变量)

function foo(a){
  b = a;  // b = 2
}
foo(2)
上面的代码执行的 LHS 查询,在非严格模式下,JavaScript 引擎在全局作用域中没有找到 b,所以它就在全局作用域中声明了一个变量 b。所以此时结果不会报错且b被赋值为2。
 

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

= 操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。

LHS 和 RHS 查询都会在当前执行作用域中开始,如果有需要(当前没找到),就会向上级作用域继续查找目标标识符(作用域链)。
不成功的 RHS 会导致抛出 ReferenceError 异常。不成功的 LHS 会自动隐式在全局作用域中创建一个全局变量(非严格模式下),该变量使用 LHS 引用的目标作为标识符。(如果是严格模式下也会抛出 ReferenceError 异常)。

JavaScript 的查询机制——LHS 与 RHS的更多相关文章

  1. js的两种查询方式 LHS and RHS

    为了进一步理解,我们需要多介绍一点编译器的术语.编译器在编译过程的第二步中生成了代码,引擎执行它时,会通过查找变量 a 来判断它是否已声明过.查找的过程由作用域进行协助,但是引擎执行怎样的查找,会影响 ...

  2. 你不知道的JavaScript(1)LHS查询和RHS查询

    打算把<你不知道的JavaScript>中的知识点整理下,写点自己的心得,同时也敦促自己看书. 先做个整体的介绍,最后会再给个综合的例子. RHS 查询与简单地查找某个变量的值别无二致,而 ...

  3. 【转】javascript中的LHS与RHS

    原文链接:http://www.cnblogs.com/yangxiaoguai132/p/5064625.html 最近在学习javascript过程中,接触了LHS与RHS的概念,刚开始的时候有点 ...

  4. javascript中的LHS和RHS

    最近在拜读<你不知道的javascript>,接触到一个比较陌生的概念,LHS查询和RHS查询. 简单的一句话来讲,当变量出现在赋值操作符的左侧时进行LHS查询,出现在右侧时进行RHS查询 ...

  5. javascript中的LHS与RHS

    最近在学习javascript过程中,接触了LHS与RHS的概念,刚开始的时候有点理解不清,现在做一些梳理,方便以后进行理解. LHS与RHS:javascript引擎的两种查找类型,含义是赋值操作的 ...

  6. 你不知道的JavaScript LHS 和 RHS 查找

    今天在学习JavaScript的相关知识时接触到了 LHS(Left Hand Side)和 RHS(Right Hand Side)两种对变量查找的方法,之所以JavaScript要查找变量,那就先 ...

  7. JavaScript中变量的LHS引述和RHS引用

    JavaScript中变量的LHS引述和RHS引用 www.MyException.Cn  网友分享于:2015-02-04  浏览:0次 JavaScript中变量的LHS引用和RHS引用 在Jav ...

  8. javascript的垃圾收集机制

    × 目录 [1]原理 [2]标记清除 [3]引用计数[4]性能问题[5]内存管理 前面的话 javascript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存.在编写javascri ...

  9. 解析Javascript事件冒泡机制

    本资源引自: 解析Javascript事件冒泡机制 - 我的程序人生 - 博客频道 - CSDN.NET http://blog.csdn.net/luanlouis/article/details/ ...

随机推荐

  1. 设置django 时间

    使用Django的DateTimeField(auro_now_add=True)设置当前时间为创建时间时,时间往往与当前时间对应不上,这是由于Django默认使用的是[UTC](世界标准时间)时区, ...

  2. SQL-W3School-高级:SQL VIEW(视图)

    ylbtech-SQL-W3School-高级:SQL VIEW(视图) 1.返回顶部 1. 视图是可视化的表. 本章讲解如何创建.更新和删除视图. SQL CREATE VIEW 语句 什么是视图? ...

  3. 阿里内部分享:我们是如何?深度定制高性能MySQL的

    阿里云资深数据库工程师赵建伟在“云栖大会上海峰会”的分享.核心是阿里云的数据库服务和MySQL分支的深度定制实践分享. 阿里巴巴MySQL在全球都是有名的.不仅是因为其性能,还因为其是全世界少数拥有M ...

  4. 014-操作系统下验证下载文件的 MD5/SHA1/SHA256

    一.mac 1.md5 openssl md5 /path/to/file 新的macOS默认支持:md5 filename 2.sha256 openssl dgst -sha256 /path/t ...

  5. Mybatis 事物回滚最简单的操作方式

    简单例子 //假设这是一个service类的片段 try{ //出现异常 } catch (Exception e) { e.printStackTrace(); //设置手动回滚 Transacti ...

  6. [activemq]+spring的使用

    一.生产端(Producer) applicationContext.xml中的配置: <?xml version="1.0" encoding="UTF-8&qu ...

  7. 10 Flutter仿京东商城项目 商品分类跳转到商品列表传值 商品列表页面布局

    pages下面新建: ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper ...

  8. Qt编写自定义控件26-平铺背景控件

    一.前言 平铺背景控件,主要的应用场景是作为画布出现,黑白相间的背景图,然后上面可以放置图片图形等,使得看起来更美观,比如PS软件新建图层以后的背景,FireWorks软件新建画布以后的透明背景,IC ...

  9. shell编程(2)

    一.变量简介 变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数据.脚本语言在定义变量时通常不需要指明类型,直接赋值即可,shell变量也遵循这个规则. 在Bash shell 中,每一个 ...

  10. LeetCode_13. Roman to Integer

    13. Roman to Integer Easy Roman numerals are represented by seven different symbols: I, V, X, L, C,  ...