编译原理

  JavaScript事实上是一门编译语言,但与传统的编译语言不同,它不是提前编译的编译结果也不能在分布式系统中进行移植

  任何JavaScript代码片段在执行前都要进行编译(通常就在执行前)。

  在传统编译语言的流程中,程序中的一段源代码在执行之前会经历三个步骤,统称为“”编译“”。

    1.分词/词法分析(Tokenizing/Lexing)

      将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元。

      分词(tokenizing)和词法分析(lexing)之间的区别:

        主要差异在于词法单元的识别是通过有状态还是无状态的方式进行的。

        如果词法单元生成器在判断a是一个独立的词法单元还是其他词法单元的一部分时,调用的是有状态的解析规则,那么这个过程就被称为词法分析。

    2.解析/语法分析(parsing)

      将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树。这个树被称为“”抽象语法树“”(Abstract Syntax Tree,AST)。

    3.代码生成

      将AST转换为可执行代码的过程被称为代码生成。

理解作用域:

    引擎:

      从头到尾负责整个JavaScript程序的编译及执行过程。

    编译器:

      引擎的好朋友之一,负责语法分析及代码生成等脏活累活

    作用域:

      引擎的另一位好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

    变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。

    引擎的查找   LHS和RHS

        当变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询。

        RHS查询与简单地查找某个变量的值别无二致,而LHS查询则是试图找到变量的容器本身,从而可以对其赋值。

        RHS并不是真正意义上的“赋值操作符的右侧”,更准确地说是“非左侧”。

        赋值操作的目标是谁(LHS)??

        谁是赋值操作的源头(RHS)??

作用域嵌套

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

异常

  如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出referenceError异常。值得注意的是,referenceError是非常重要的异常类型。

  当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎,前提是程序运行在非“严格模式”下。

    在严格模式中LHS查询失败时,并不会创建并返回一个全局变量,引擎会抛出同RHS查询失败时类似的referenceError异常。

  若RHS查询找到了一个变量,但是你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值中的属性,那么引擎会抛出另外一种类型的异常,叫做TypeError。

  ReferenceError同作用域判别失败相关,而typeError则代表作用域判别成功了,但是对结果的操作是非法或不合理的。

小结:

  作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对变量进行赋值,那么就会使用LHS查询;如果目的是获取变量的值,就会使用RHS查询。赋值操作符会导致LHS查询。=操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。

  JavaScript引擎首先会在代码执行前对其进行编译,在这个过程中,像var a=2这样的声明会被分解成两个独立的步骤:

    1.首先,var a 在其作用域中声明新变量。这会在最开始的阶段,也就是代码执行前进行。

    2.接下来,a=2会查询(LHS查询)变量a并对其进行赋值。

  LHS和RHS查询都会在当前执行作用域中开始,如果有需要(也就是说它们没有找到所需的标识符),就会向上级作用域继续查找目标标识符,这样每次上升一级作用域(一层楼),最后抵达全局作用域(顶层),无论找到或没找到都将停止。

  不成功的RHS引用会导致抛出referenceError异常,不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出referenceError异常(严格模式下)。

你不知道的JavaScript——第一章:作用域是什么?的更多相关文章

  1. 你不知道的javaScript上卷(第一章 作用域是什么)

    在写这篇博客时这本书我已经是看过一遍了,为了加深印象和深入学习于是打算做这系列的前端经典书籍导读博文,大家如果觉得这本书讲的好可以自己买来看看,我是比较喜欢看纸质版书的,因为这样才有读书的那种感觉. ...

  2. 你不知道的JavaScript——第二章:this全面解析

    1调用位置 调用栈:为了到达当前执行位置所调用的所有函数. function baz(){ //当前调用栈:baz //因此,当前调用位置是全局作用域 console.log('baz'); bar( ...

  3. JavaScript 第一章总结

    A quick dip into javascipt The way JavaScript works HTML 用一系列的 markup 来呈现整个 content 的 structure.CSS ...

  4. 重温Javascript第一章

    一.script标签 script标签有6个属性,其中一个废弃,五个可选. 按照传统的写法,<script>的标签都是放在<head>元素中,但是在<head>中包 ...

  5. 【读书笔记】你不知道的JavaScript(上卷)--作用域是什么

    第一章 作用域 1.理解作用域 几个名词的介绍 引擎:从头到尾负责整个JavaScript程序的编译及执行过程 编译器:负责语法分析及代码生成器等脏活累活 作用域:负责收集并维护由所有声明的标识符(变 ...

  6. 你不知道的JavaScript(上)作用域与闭包

    第一部分 作用域与闭包 第一章 作用域是什么 1.作用域 变量赋值操作会执行两个动作:首先编译器会在当前作用域中声明一个变量(如果之前没有声明过), 然后会在运行时引擎会在作用域中查找该变量,找到就会 ...

  7. 《你不知道的js》 ------1.作用域是什么

    相关定义 引擎:从头到尾负责整个JavaScript程序的编译及执行过程. 编译器:负责语法分析及代码生成等. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规 ...

  8. 你不知道的JavaScript 上卷 2/11

    第一部分——作用域和闭包 第一章 作用域是什么 1.几乎所有编程语言最基本的功能之一,就是能够储存变量当中的值,并且能在之后对这个值进行访问或修改.事实上,正是这种储存和访问变量的值的能力将状态带给了 ...

  9. 《你不知道的JavaScript》第一部分:作用域和闭包

    第1章 作用域是什么 抛出问题:程序中的变量存储在哪里?程序需要时,如何找到它们? 设计 作用域 的目的:为了更好地存储和访问变量. 作用域:根据名称查找变量的一套规则,用于确定在何处以及如何查找变量 ...

随机推荐

  1. 【NOI2018模拟】Yja

    [NOI2018模拟]Yja Description 在平面上找\(n\)个点,要求这 \(n\)个点离原点的距离分别为 \(r1,r2,...,rn\) .最大化这\(n\) 个点构成的凸包面积,凸 ...

  2. 洛谷P2845-Switching on the Lights 开关灯

    Problem 洛谷P2845-Switching on the Lights 开关灯 Accept: 154    Submit: 499Time Limit: 1000 mSec    Memor ...

  3. WIN10 企业版 LTSC 激活

    Windows10 企业版长期服务支持分支版本: Windows 10 LTSC 2019 WIN+X 选POWERSHELL 管理员版本 输入以下 slmgr -ipk M7XTQ-FN8P6-TT ...

  4. RESTful学习笔记

    作为一名只有几个月IT自学经历的人,在接受新知识的时候总是想找到浅显易懂的方式去理解,但往往却很难找到相关的文章,大部分都是针对具有一定经验的开发人员,因此在看了很多相关的文章才对RESTful架构有 ...

  5. [HEOI2016/TJOI2016]求和

    嘟嘟嘟 好多人(神仙)都说这是NTT例题,然后我就做了-- 做这题,需要一下前置技能: 1.第二类斯特林数 2.NTT 3.没有公式恐惧症 额--不会斯特林数的话(就像我),知道通项公式也行. 这个博 ...

  6. 第一章 mysql的体系结构与存储引擎

    数据库从逻辑上可以分为两部分,一部分负责存储即文件系统,这部分有个更时髦的名字叫存储引擎,存储引擎负责如何把数据以及索引相关的内容以合适的形式组织并存储到磁盘上.另一部分为server部分,负责和用户 ...

  7. mysql创建索引的原则

    在mysql中使用索引的原则有以下几点: 1. 对于查询频率高的字段创建索引: 2. 对排序.分组.联合查询频率高的字段创建索引: 3. 索引的数目不宜太多 原因:a.每创建一个索引都会占用相应的物理 ...

  8. ssm框架整合+Ajax异步验证

    SSM框架是目前企业比较常用的框架之一,它的灵活性.安全性相对于SSH有一定的优势.说到这,谈谈SSM和SSH的不同点,这也是企业常考初级程序员的面试题之一.说到这两套框架的不同,主要是持久层框架Hi ...

  9. BZOJ1004 HNOI2008 Cards Burnside、背包

    传送门 在没做这道题之前天真的我以为\(Polya\)可以完全替代\(Burnside\) 考虑\(Burnside\)引理,它要求的是对于置换群中的每一种置换的不动点的数量. 既然是不动点,那么对于 ...

  10. Luogu P3321 [SDOI2015]序列统计

    一道不错的多项式好题.还涉及了一些数论内容. 首先我们看到题目是求乘积模\(m\)的方案数,考虑到这种方案数我们一般都可以用生成函数来做. 但显然卷积的下标有加(FFT,NTT等)有位运算(FWT)但 ...