本系列是自己读你不知道的JS一本书的笔记。有一些模糊的概念或者不清楚的东西自己写成了一个系列的读书笔记。分享出来,方便大家共同学习进步。
这篇笔记只写了自己不明白的,书籍中写的好的地方的笔记;一些函数作用域,块级作用域等都能搜到的东西就没有再一次记录了
第1章:作用域是什么
一、编译原理
几乎所有编程语言最基本的功能之一,就是能够储存变量当中的值,并且能在之后对这个 值进行访问或修改。事实上,正是这种储存和访问变量的值的能力将 状态 带给了程序。
若没有了状态这个概念,程序虽然也能够执行一些简单的任务,但它会受到高度限制,做 不到非常有趣。
但是将变量引入程序会引起几个很有意思的问题,也正是我们将要讨论的:这些变量 哪里?换句话说,它们储存在哪里?最重要的是,程序需要时如何找到它们?
这些问题说明需要一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量。 这套规则被称为 作用域 。
在传统编译语言的流程中,程序中的一段源代码在执行 之前 会经历三个步骤,统称为“编 译”。
-
分词/语法分析
这个过程会将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代 码块被称为词法单元(token)。例如,考虑程序 var a = 2; 。这段程序通常会被分解成 为下面这些词法单元: var 、 a 、 = 、 2 、 ; 。空格是否会被当作词法单元,取决于空格在 这门语言中是否具有意义。
-
解析/语法分析
这个过程是将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树。这个树被称为“抽象语法树”(Abstract Syntax Tree,AST)。var a = 2; 的抽象语法树中可能会有一个叫作 VariableDeclaration 的顶级节点,接下 来是一个叫作 Identifier (它的值是 a )的子节点,以及一个叫作 AssignmentExpression 的子节点。 AssignmentExpression 节点有一个叫作 NumericLiteral (它的值是 2 )的子 节点。
-
代码生成
将 AST 转换为可执行代码的过程称被称为代码生成。这个过程与语言、目标平台等息 息相关。抛开具体细节,简单来说就是有某种方法可以将 var a = 2; 的 AST 转化为一组机器指 令,用来 创建 一个叫作 a 的变量(包括分配内存等),并将一个值储存在 a 中。
二、作用域嵌套
把作用域链比喻成一个建筑为了将作用域处理的过程可视化,我希望你在脑中想象下面这个高大的建筑: evernotecid://24EF8D48-9B46-4416-B9E4-9C3110C0181A/appyinxiangcom/19783202/ENResource/p766
这个建筑代表程序中的嵌套作用域链。第一层楼代表当前的执行作用域,也就是你所处的 位置。建筑的顶层代表全局作用域。