编译原理

  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. Django-rest-framework 接口实现 rest_framework 中有已经定义好的 工具类 mixins generics viewsets

    rest_framework.mixins 请求业务 的 5 种实现 ​ mixin(混合类):不能单独使用,和其它类搭配起来使用(利用了Python支持多继承) rest_framework.mix ...

  2. centos7下安装docker(13.4容器volume总结)

    最近我们学习了docker 存储,首先docker存储有两种:storage driver和data volume. storage driver是由镜像层和容器层组成的,可以通过docker ins ...

  3. CSS--块级元素和行内元素

    相同:设置后,对应的模块都会脱离文档流 不同点:position相应的块级元素会覆盖下面的内容(文字,),而float只会覆盖块级元素,里面的文字会脱离 出来 float是浮动定位,position是 ...

  4. 转://云和恩墨的两道Oracle面试题

    真题1. 对于一个NUMBER(1)的列,如果查询中的WHERE条件分别是大于3和大于等于4,那么这二者是否等价? 答案:首先对于查询结果而言,二者没有任何区别.从这一点上讲无论是指定大于3还是指定大 ...

  5. 转://因触发器限制导致oracle用户登录失败

    使用PL/SQL DEV登录数据库时,出现如下错误 手工创建了test用户,通过dev工具登录没问题.怀疑数据库中有些用户限制了登录的.再看错误编号:ORA-20001,oracle保留的异常错误号范 ...

  6. 电脑如何用HDMI连接电视

    因为现在的液晶电视基本上都有VGA接口,所以你可以很容易地用VGA线实现电脑连接电视上,但是该文有一个地方没有提到,那就是分辨率的问 题,现在的液晶电视的主流面板已经是全高清面板(1920X1080) ...

  7. stroop效应matlab实验

    1 打开matlab,打开test1.m 点击运行,若出现选择 更改文件夹 2  引导界面 (在这个界面,只许用户鼠标点击开始,其余的别乱按按键. 记得将打字法关掉,切换到小写) 3 做题界面 根据颜 ...

  8. mysql之grant权限说明

    mysql中给一个用户授权如select,insert,update,delete等其中的一个或者多个权限,主要使用grant命令,格式为: 给没有用户授权 grant 权限 on 数据库对象 to ...

  9. 二分法binadySearch的用法

    package com.Summer_0420.cn; import java.util.Arrays; /** * @author Summer * 二分法binadySearch的用法(测试) * ...

  10. MySQL报错: java.sql.SQLException: Column count doesn't match value count at row 1

    这个是今天写新项目的是后,写插入语句测试用例的时候报这个错误, 其实错误的原因就是插入语句的前面的列和后面的值 的个数不对. 错在此,仔细检查一下,看看少了哪一个,然后修改就可以了.