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 异常)。

最新文章

  1. jQuery小技巧
  2. Android-----搭建开发环境AND模拟器配置AND启动项目
  3. Blackfin DSP(六):BF533的SPORT接口
  4. uva 10340 All in All
  5. Entity Framework简介
  6. 【leetcode】String to Integer (atoi)
  7. Java8新特性之一、时间日期API
  8. javascript数组详解
  9. (转载)Mysql中,SQL语句长度限制
  10. C++ Template Specialization (模板特化)
  11. Storm的数据可靠性(理论)
  12. 转:shell比较两个字符串是否相等
  13. int a[5]={1,2,3,4,5};printf("%d\n", *((int*)(&a+1)-2);
  14. 第13天 JSTL标签、MVC设计模式、BeanUtils工具类
  15. Android线程之Thread 、Runnable 的两个例子
  16. Hibernate懒加载的三种解决方案
  17. SQL练习题完整(做完你就是高手)
  18. Helix Streaming Server 简单配置
  19. 使用Keepalived构建LVS高可用集群
  20. mysql把一个查询结果当作一个子集来查询

热门文章

  1. RAID概念记录
  2. python抽取指定url页面的title方法
  3. python之inspect模块
  4. Docker跨主机网络实践
  5. 【Matlab开发】matlab中norm范数以及向量点积、绘图设置相关
  6. Java学习笔记-包装类
  7. MyBatis使用技巧、总结、注意事项
  8. 修改ssh登录的初始目录
  9. POJ 1789 Truck History【最小生成树模板题Kruscal】
  10. 将一个整数数组先按照因子数量排序,再按照数字大小排序,输出第k个数