编译型语言&解释型语言
编译型: 在代码运行前 编译器将人写好的语言 转换成机器可以识别的的语言
解释型: 在代码运行时 将人写好的语言转换成机器可以识别的语言
解释型语言: 需要在代码执行前将解释器装在环境中,解释型编译几乎在执行后一瞬间就开始,几乎没有代码优化
编译型语言: 在代码写好后再通过编译之后直接就可以运行,运行的是编译完成的代码
JavaScript一般被归类为动态语言,或者叫做解释执行语言,其实也可以看做是一种编译语言,但是它不是提前编译好的,编译结果也不能在分布式系统中移植,js的编译过程不是发生在构建之前,大部分情况下编译发生在代码的执行之前很短的时间里。 这是因为js存在变量提升,解释型无法做到这点
JS的编译过程
例如 var a = 2;
一. 分词/词法分析
词法分析,也叫做扫描scanner。它读取我们的代码,然后把它们按照预定的规则合并成一个个的标识Tokens(type 和 value )。这个阶段,它会移除空白符,注释等。最后,整个代码将被分割进一个Tokens列表(一个一维数组)。
[
{'type':'Keyword','value':'var'},
{'type':'Identifier','value':'a'},
{'type':'Punctuator','value':'='},
{'type':'Numeric','value':'1'},
{'type':'Punctuator','value':';'},
]
二. 解析/语法分析
将词法流转换成 “抽象语法树”(AST),同时,验证语法,语法如果有错的话,抛出语法错误。
{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "a"
},
"init": {
"type": "Literal",
"value": 2,
"raw": "1"
}
}
],
"kind": "var"
},
],
"sourceType": "script"
}
-
type(表示是一段程序代码)
表示这个内容块是干什么的 -
body(代码的具体内容)
代码的具体内容 -
declarations(变量内容的块)
可以看到这个块也是一个数组,因为变量声明可能多个,所以一个声明对应一个对象
- type (声明的类型是个变量)
- id(表示变量名)
- init(表示为这个变量设置的初值) -
sourceType(表示语言的种类)
表示语言的种类
三.代码生成
将AST转换为可执行代码的过程称被称为代码生成。
-
预编译阶段
预编译阶段 会创建执行上下文(创建作用域,创建变量对象(不赋值),确定this的指向)
(其中初始化创建 Arguments对象(获取形参并赋值),函数声明(并赋值),变量声明,函数表达式声明(未赋值))
每次进入不同的运行环境都会创建 一个相应的执行上下文。
在一段js程序中一般都会创建多个执行上下文。
js引擎会以栈的数据结构对这些执行进行处理,形成函数调用栈(call stack),
栈底永远是全局执行上下文(global execution context),栈顶则永远时当前的执行上下文。 -
执行阶段
- 变量赋值 ,函数表达式赋值
- 调用函数
- 顺序执行其它代码
创建阶段对函数声明做赋值,变量及函数表达式仅做声明,真正的赋值操作要等到执行上下文代码执行阶段。
本文深入探讨了JavaScript作为解释型语言的编译过程,包括词法分析、语法分析和代码生成三个关键步骤,揭示了JS如何从源代码转化为可执行代码。

被折叠的 条评论
为什么被折叠?



