大家好,我是鼠目。「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」
本文主要谈论javaScript预编译。
javaScript是解释性语言
众所周知,javascript是一门解释性语言,也就是即时编译。它与传统编译型语言不同,并不需要提前将源码编译生产机器语言。(计算机并不能直接识别高级语言)而是通过内置的js引擎,在代码执行前的极短时间内,进行编译。也就是预编译。
tips: java有提前编译步骤,但是不是编译成机器码直接在计算机中直接运行,而是编译成字节码在JVM中运行。所以,java在我看来不算是严格的编译型语言。
js引擎执行js代码的三部曲。
-
词法分析(会将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元)
-
预编译 (本章详谈的内容,js的执行过程会先对整体语法进行扫描,若存在逻辑错误或者语法错误,将会抛出错误,停止执行。否则,在变量声明和函数声明时,进行预编译。此时不进行赋值,也就是没有初始化行为。匿名函数,不参与预编译)
-
解释执行 (从上到下,解释一行,执行一行)
预编译
预编译分为两个部分,全局预编译与局部预编译
全局预编译,优先进行
- 创建GO对象(Global Object) 全局对象
- 查找变量名,作为GO对象的属性,初始化为undefined
- 查找函数声明,作为GO属性,将函数体作为值 (这一步,并不会执行函数体内的内容,所以函数体内,对于我们而言,依旧是未知领域)
var run;
console.log(run)
run()
function run(){
console.log("run")
}
//1. 创建全局GO对象
//2. 查找变量名,GO.run = undefined,变量声明提升
//3. 查找函数声明,GO.run = function,函数声明提升
// 预编译完成后,开始执行
// 打印 function
// 执行run 打印run
// 反之如果将 var run -> var run = 1;则会抛出错误
遇到函数执行语句,开始对函数内的内容进行预编译。也就是局部预编译
局部预编译
- 创建AO对象(Activation Object)
- 寻找形参和变量声明,将形参名和变量作为AO属性名,赋值undefined
- 实参和形参相统一
- 函数体内,查找函数声明(函数嵌套函数)
function run(a, b) {
var c = 1;
}
run (1,2)
// AO对象
// 形参 a,b 变量c
// 相统一 a=1 b=2
// 查找函数声明