开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
什么是作用域
作用域,几乎是在所有的编程语言中都需要的一套规则。
在写程序时,都需要用变量来存储值,存储之后,放到哪里?当后面需要用到的时候要到哪里去寻找这个变量呢?这些问题都需要一套严谨的规则来定义,否则就得乱套,编写的程序就不会稳定的被执行。
这套规则就称为作用域。
编译原理
我们都知道,JavaScript是动态、弱类型语言。弱类型指的是它对变量类型没有严格要求,在运行时初始变量定义是数字,也可以被字符串赋值,仍能正常运行。而静态/动态说的是在编译阶段是否能确定变量的类型。
JavaScript虽然是动态解释执行语言,事实上它也是一门编译语言,只是有所不同的是,它不是提前编译的,也不能在分布式系统进行移植,并且它仅仅是在执行前很短的时间内编译完成。
传统的编译大致有三个阶段
分词/词法分析(Tokenizing/Lexing)
这个过程是将代码分解成独立的有意义的词法单元(token)。例如:
// 会被解析为let、a、=、1,至于空格是否会被作为独立的toking,取决于空格对于程序语言是否有独特的意义
let a = 1
分词和词法分析两者之间也有微妙的差异:在代码解析成token的过程是否调用的是有状态的解析规则,调用了就称为词法分析;调用的是无状态解析规则,就是分词。
解析/语法分析(Parsing)
语法分析是将上一步解析的token进一步解析成抽象语法树(Abstract Syntax Tree, AST)。
抽象语法树是将一个表达式通过树形结构来表示。
代码生成
将AST转化为可执行代码的过程。这个过程与编程语言、平台息息相关,因为转换后的代码由对应的平台或解释器来执行。
以上编译三大步骤只是各语言通用的,在具体的语言编译过程中要复杂的多。