
本文共 2276 字,大约阅读时间需要 7 分钟。
JS运行过程解析
JS运行过程简述
JS运行过程主要包含以下几个阶段:语法分析、预编译和解释执行。这些阶段共同构成了 JavaScript 引擎执行代码的完整流程。
JS预编译过程(在函数执行的前一刻进行)
在函数执行之前,JavaScript 引擎会进行一次预编译。预编译的主要目的是为函数创建执行期上下文(AO),并对变量和函数进行适当的处理。
1. 创建执行期上下文(AO)
执行期上下文(AO)是函数执行的核心对象,主要负责管理变量、函数以及其他运行时上下文信息。在预编译阶段,AO 会被创建,并初始化为空对象。
2. 找形参和变量声明,赋值为 undefined
在预编译阶段,引擎会遍历函数体,找出所有的变量声明和形参。这些变量会被赋值为 undefined
,以便在后续的解释执行阶段进行初始化或赋值。
3. 形参实参与形参相统一
引擎会将函数传入的实际参数(实参)与函数定义的形参进行统一。如果实参的数量多于形参数量,多余的参数会被忽略;如果形参数量多于实参数量,未提供的形参会被赋值为 undefined
。
4. 找函数声明,并赋予函数体
在预编译阶段,引擎会找出函数声明,并将这些函数赋予其对应的函数体。需要注意的是,匿名函数和函数表达式不会被包含在预编译过程中。
eg1: 代码解析
function a(a) { var a = 123; function a() {} var b = function() {} function d() {}}fn(1);
1. 预编译阶段
第一步:创建 AO 对象
预编译开始时,引擎会创建一个空的 AO 对象。
第二步:找形参和变量声明
在函数 a
中,引擎会找到形参 a
和变量 a
、b
、d
,并将它们赋值为 undefined
。
第三步:形参实参与形参相统一
函数 a
的形参 a
被赋值为实参 1
,变量 b
和 d
保持 undefined
。
第四步:找函数声明
引擎会找到函数 a()
和 d()
的声明,并将它们赋予相应的函数体。
2. 解释执行阶段
第一行:a = 123
执行 a = 123
,此时 a
在 AO 对象中被赋值为 123
。
第二行:函数内部的预编译已经完成
由于函数内部的代码已经被预编译,直接执行。
第三行:b = function() {}
执行 b = function() {}
,将 b
赋值为函数表达式。
第四行:函数内部的预编译已经完成
继续执行。
第五行:console.log(a)
输出 a
的值 123
。
第六行:console.log(b)
输出 b
的值 function() {}
。
第七行:函数内部的预编译已经完成
继续执行。
第八行:fn(1)
执行 fn(1)
,即调用函数 fn
并传入参数 1
。
eg2: 代码解析
function fn(a) { console.log(a); // function a() {} var a = 123; //123 console.log(a); //123 function a() {}; //123 console.log(a); //123 var b = function() {}; // function(){} console.log(b); // function() {} function d() {}; // function d() {}}fn(1);
1. 预编译阶段
第一步:创建 AO 对象
预编译开始时,引擎会创建一个空的 AO 对象。
第二步:找形参和变量声明
在函数 fn
中,引擎会找到形参 a
和变量 a
、b
、d
,并将它们赋值为 undefined
。
第三步:形参实参与形参相统一
函数 fn
的形参 a
被赋值为实参 1
,变量 b
和 d
保持 undefined
。
第四步:找函数声明
引擎会找到函数 a()
和 d()
的声明,并将它们赋予相应的函数体。
2. 解释执行阶段
第一行:console.log(a)
输出 a
的值 function a(){}
。
第二行:a = 123
执行 a = 123
,此时 a
在 AO 对象中被赋值为 123
。
第三行:console.log(a)
输出 a
的值 123
。
第四行:function a() {}
执行 function a() {}
,即定义了一个新的函数 a
。
第五行:console.log(a)
输出 a
的值 123
。
第六行:var b = function() {}
执行 var b = function() {}
,将 b
赋值为函数表达式。
第七行:console.log(b)
输出 b
的值 function() {}
。
第八行:function d() {}
执行 function d() {}
,即定义了一个新的函数 d
。
第九行:console.log(d)
输出 d
的值 function d() {}
。
第十行:fn(1)
执行 fn(1)
,即调用函数 fn
并传入参数 1
。
最终输出结果
function a() {}a = 123;function a() {}b = function() {};function d() {};fn(1);
以上是对代码的解释执行过程,具体输出结果可能因环境而异。
发表评论
最新留言
关于作者
