深入解析JavaScript执行模型:从脚本加载到作用域链

作者:木棉

时间:2026-10-25

浏览:80

本文深入解析JavaScript的执行模型,涵盖脚本加载、语法分析、全局与函数执行环境的创建机制。详细阐述Variable Object(变量对象)在不同环境下的行为差异,以及作用域链(Scope Chain)如何通过链表结构实现变量查找,帮助开发者理解JS运行时核心原理。

文章目录

JavaScript脚本加载与执行流程

引言


基础代码示例:


具体实现如下:

 
<script type="text/javascript" src="xxx.js"></script>
<script type="text/javascript">
var i = 10;
function say(msg){
alert(msg);
} 
</script>
<script type="text/javascript">
j=100;
say("hello world");
</script>

上述代码片段的执行流程如下:


具体实现如下:

 
步骤1. 加载首个代码段
步骤2. 进行语法解析,若发现错误(如括号不匹配)则报告语法错误,并跳转至步骤5
步骤3. 建立全局执行环境(对var变量声明和function定义进行‘预解析’处理)
步骤4. 执行代码段(调用函数或进入eval时会创建新的执行环境),若出错则报错(如变量未定义)
步骤5. 若存在后续代码段,则加载下一个代码段,并重复步骤2
步骤6. 执行结束

在步骤1中,‘脚本段’特指<script>... ...</script>标签内的内容,同时也涵盖通过外部引入的脚本文件,例如<script src="xxx.js"></script>同样属于脚本段的范畴。那么,步骤2中的语法分析具体指什么?通俗而言,语法分析即检查Javascript代码的语法结构是否合法。例如:


具体实现如下:

 
<script type="text/javascript">
var a = 10;
if(a>10{
alert('yes');
} 
</script>

显然,该代码无法通过语法分析,因为if条件语句的书写语法存在错误。步骤3和步骤4中提到的‘执行环境’究竟指代什么?全局执行环境与调用函数时创建的执行环境有何区别?执行环境内部又包含哪些处理机制?... ...



注:下文部分内容源自原《javascript提速_01_引用变量优化》一文的前两节完整版本。



执行环境(Execution Context)详解

关于执行环境(Execution Context)


所有JavaScript代码均在特定的执行环境中运行。这是一个概念及机制,用于处理JavaScript运行时的作用域、生命周期等问题。



可执行的JavaScript代码主要分为三种类型:


1. Global Code,即全局代码,指不在任何函数内部的代码,例如一个独立的js文件或嵌入在HTML页面中的js代码等。


2. Eval Code,即通过eval()函数动态执行的JS代码。


3. Function Code,即用户自定义函数体内的JS代码。


不同类型的JavaScript代码拥有不同的Execution Context



在页面首次加载JS代码时,系统会创建一个全局执行环境。当调用一个JavaScript函数时,该函数便进入相应的执行环境。若再次调用其他函数(或递归调用同一函数),则会创建一个新的执行环境,且在函数调用期间,执行过程均处于该环境中。当被调用的函数返回后,执行过程将回到原始执行环境。因此,运行中的JavaScript代码构成了一个执行环境栈。



以下通过一个示例进行说明:


具体实现如下:

 
<script type="text/javascript">
function Fn1(){
function Fn2(){
alert(document.body.tagName);//BODY
//other code...
} 
Fn2();
} 
Fn1();
//code here
</script>

JavaScript脚本加载与执行流程

上述程序从上至下执行时的执行环境栈情况如图所示。



补充说明:


全局执行环境对应的是Global Code(全局代码)


Fn1执行环境、Fn2执行环境统称为函数执行环境,对应的是Function Code(函数定义代码)



程序在进入每个执行环境时,都会创建一个名为Variable Object的对象。


针对函数执行环境,函数对应的每一个参数、局部变量、内部方法都会在Variable Object上创建一个属性,属性名为变量名,属性值为变量值。全局执行环境具有相同的行为。但需强调一点:在全局执行环境中,Variable Object即为Global Object,关于Global Object在《理解Javascript_03_javascript全局观》中已有说明,可简单理解为window对象。这也解释了为何全局方法和全局变量均为window对象的属性或方法,请看如下代码:


具体实现如下:

 
var num = 123;
alert(window.num);//123
function say(msg){
alert(msg);
} 
window.say("hello");//hello

最后需要指出,Variable Object对象是一个内部对象,JS代码中无法直接访问。



作用域链(Scope Chain)机制

关于Scope/Scope Chain


在访问变量时,必然涉及可见性问题,即Scope。更深入地说,当访问变量或调用函数时,JavaScript引擎会按照特定规则,将不同执行位置上的Variable Object构建为一个链表。在访问变量时,引擎先在链表的第一个Variable Object上查找,若未找到,则继续在第二个Variable Object上查找,直至搜索结束。由此形成了Scope Chain的概念。


JavaScript脚本加载与执行流程

作用域链图清晰展示了执行环境与作用域的关系(一一对应),以及作用域之间的关系(链表结构,由上至下)。



注:本文仅从全局视角探讨javascript执行模型,因此不够深入。具体执行细节,请参阅后续博文。



参考:


http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html


http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html


http://lifesinger.org/blog/2009/01/javascript-run-mechanism/

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章