首页 > 再说说作用域

再说说作用域

javascript的作用域是一个老生常谈的问题了。高程啊,或是各种书籍上都有关于javascript的作用域的阐述。这一次看了,《你不知道的JavaScript》里关于作用域的描述,感觉挺不错的。

编译

JavaScript是脚本语言,解释型语言,很多人可能认为它要跟其他的编译型语言划分界限,毫不相干。但是JavaScript确实是有“编译”的。不过与一众编译型语言不同,JavaScript进行的是预编译,这个编译发生在代码执行前的几微妙。

跟作用域相关的角色

主要有三:

  1. 引擎:从头到尾负责整个JavaScript程序的编译和执行过程。
  2. 编译器:负责语法分析,代码生成。
  3. 作用域:负责收集并维护由所有声明的标识符组成的一系列查询,并实施一套非常严格的规则,确定当前执行代码对这些标识符的访问权限。

看个例子

var a = 2;

大家常常会把这句语句的执行过程想成这样:为一个变量分配内存,并命名为a,然后将2这个值保存进这个变量。

然后,这并不完成正确。

实际情况是比较复杂的。大概的过程如下:

  1. 对于var a,编译器询问作用域是否已经有一个名为a的变量存在于当前作用域中,如果有,这个声明会被忽略。如果没有,就会在当前作用域的集合中声明一个新的变量,命名为a。
  2. 对于a = 2部分,引擎在运行时会询问当前作用域,是否有这个名为a的变量,如果有,引擎使用这个变量。如果没有,向上一级作用域寻找。

声明发生在编译,赋值则是运行时候的事情了。

LHS和RHS

LHS和RHS是引擎对变量的两种查询手段。简单来说,L和R分别代表左侧和右侧。再简单来说,左侧就是指如果要对一个变量进行赋值,那么我们要知道的是是否有这个变量,也就是找到操作的目标,我们不关心它的值。右侧是指我们要取得某个变量的指时。

用个例子说明:

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

LHS查询:

  1. 第2行,var b
  2. 第5行,var c
  3. 第5行,foo(2)里的2,

    RHS查询:
  4. 第2行,第2行,b = a
  5. 第3行, a + b 里的a
  6. 第3行, a + b 里的b
  7. 第5行中对于函数的调用。

作用域嵌套

LHS和RHS查询都会再当前执行作用域中开始,如果有需要(也就是说它们没有找到所需的标识符),就会向上一级作用域继续查询目标标识符。要是一直都找不到就会查询到全局作用域为止。

转载于:https://www.cnblogs.com/xzhx/p/8403739.html

更多相关:

  • JavaScript采用的是词法作用域 1.词法作用域 即函数定义时,即确定的作用域。js中的作用域链,在函数声明时候,就已经确定了,无论函数在何处调用,其作用域变量的查找都是按照定义是包含关系去查找。 2.动态作用域 变量的作用域与函数的调用地点有关,在不同的函数中调用,变量的查找会沿着调用函数向上查找。 举例: var a =...

  • 多线程编程 mind-Mapping保存有一下导图的xmind文件,可直接获取 互斥变量 互斥对象 ptrhead相关接口 条件变量 future异步访问类 async类 promise类 package_task类...

  • 我们在实际开发的过程中,可能需要某些类的成员变量并不是针对每一个对象的,而是针对每一个类而言的,比如在银行中有一个利率数据,我们希望的是,当一个利率改变的时候,所有的对象都能够看到这个改变的数据,并利用它,而不是每一个对象都有一个利率成员变量。这个时候就设计到了静态成员变量。 一. 内存那些事 静态成员变量是存放在静态...

  • volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。在DSP开发中,经常需要等待某个事件的触...

  •   引子     阅读以下代码,并尝试分析 代码解析 在主线程中,线程Id为1,为线程变量赋值 变量==d6ff开启一个新的task,此时线程Id为4,变量==d6ff,并调用Task1开启一个同步Task3,线程Id为1。变量==d6ff,修改值==f598此时第二步启动的Task1运行,线程Id为4,变量==d6ff,修改值=...

  • 操作系统基础    操作系统是协调、控制、管理计算机硬件资源与软件资源的控制程序 为什么要用操作系统?    1.操作系统可以把复杂的操作简化给用户使用或者应用程序  2.可以让应用程序对计算机硬件竞争变的有序  一套完整的计算机分为:操作系统、应用程序、计算机硬件 编程语言的分类   机械语言:使用二进制让计算机工作   优点:运行...

  • 关注我的头条号,获取更多运维相关知识。你想了解哪方面的运维知识,请评论区告诉我,我会尽快更新~MySQL 数据库,基本上运维都会接触到,而对于数据库的性能优化,想必是大家比较关注的,下面分享一些调优技巧。先决条件安装 MySQL,版本大于 5.7有部分数据操作系统、数据库管理员权限MySQL 系统性能优化在系统层面,调整硬件和软件选项...

  • spring data jpa提供了多种查询方式,如下:方法名称查询继承Repository接口测试代码方法名称中支持的关键字(官方文档提供)使用JPA命名查询在User实体中定义jpql(类似于hql)jpql(百度百科)继承JpaRepository接口测试使用@Query查询和命名查询不同的是,将jpql写到了 dao 方法上,...

  • 转自:http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.html   对于SqlServer的优化来说,可能优化查询是很常见的事情。关于数据库的优化,本身也是一个涉及面比较的广的话题,本文只谈优化查询时如何看懂SqlServer查询计划。由于我对SqlServer的认识...

  • 一.实现基础功能之一(记账)   一个记账本最基础之一的功能就是记账,所以也是首先要解决的问题,我选择了上学期使用的MySQL数据库来对账本进行存储。   我选择记账的方法是分开记账,就是支出放在一个表,收入放在一个表,这样在数据库方面会比较的直观的看到,但是在显示的时候就会产生部美观的问题,就是支出和收入都是分开来的,没有办法按照时...

  • 在Navicat中,我们选中一个表,双击打开,这是如果要新建查询这个表的sql语句,可以直接用快捷键  ctrl+q  会自动打开查询窗口,并直接写好 sql:select * from (当前打开的表名) 我们直接在后面补全查询条件即可,非常方便。 转载于:https://www.cnblogs.com/libin6505/...