理解Javascript_12_执行模型浅析


Posted in Javascript onOctober 18, 2010

简单的开始
简单的代码:

<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>

上面代码段的运行顺序是:
step1. 读入第一个代码段 
step2. 做语法分析,有错则报语法错误(比如括号不匹配等),并跳转到step5 
step3. 创建全局执行环境(对var变量和function定义做"预解析") 
step4. 执行代码段(调用函数、进入eval时,都会创建新的执行环境),有错则报错(比如变量未定义) 
step5. 如果还有下一个代码段,则读入下一个代码段,重复step2 
step6. 结束

对于step1中的'脚本段'指的是<script>... ...</script>标签中的内容,还包括外部引入的脚本文件,如<script src="xxx.js"></script>也被列是脚本段的范畴。那step2中的语法分析又是什么呢?简单的理解语法分析就是查看Javascript代码的语法结构是否正确。如:
<script type="text/javascript"> 
var a = 10; 
if(a>10{ 
alert('yes'); 
} 
</script>

很明显,代码无法通过语法分析,if这个条件语句的输写语法是错误的。step3和step4中的'执行环境'是指什么,全局执行环境和调用函数创建的执行环境有什么区别?执行环境内部又有哪些处理?... ...

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

关于执行环境(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_12_执行模型浅析
以上是程序从上到下执行时的执行环境栈情况图。

补充说明:
全局执行环境对应的是Global Code(全局代码)
Fn1执行环境、Fn2执行环境通称为函数执行环境对应的是Function Code(函数定义代码)

程序在进入每个执行环境的时候都会创建一个叫做Variable Object的对象。
针对于函数执行环境,函数对应的每一个参数、局部变量、内部方法都会在Variable Object上创建一个属性,属性名为变量名,属性值为变量值。针对于全局执行环境,具有相同的行为。但是要强调的一点是在全局执行环境中Varible 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/Scope Chain
在访问变量时,就必须存在一个可见性的问题,这就是Scope。更深入的说,当访问一个变量或调用一个函数时,JavaScript引擎将不同执行位置上的Variable Object按照规则构建一个链表,在访问一个变量时,先在链表的第一个Variable Object上查找,如果没有找到则继续在第二个Variable Object上查找,直到搜索结束。这也就形成了Scope Chain的概念。
理解Javascript_12_执行模型浅析
作用域链图,清楚的表达了执行环境与作用域的关系(一一对应的关系),作用域与作用域之间的关系(链表结构,由上至下的关系)。

注:本文仅仅从全局角度的看待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/

Javascript 相关文章推荐
jquery 批量上传图片实现代码
Jan 28 Javascript
再谈querySelector和querySelectorAll的区别与联系
Apr 20 Javascript
ie8 不支持new Date(2012-11-10)问题的解决方法
Jul 31 Javascript
js获取系统的根路径实现介绍
Sep 08 Javascript
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
Jun 24 Javascript
javascript显式类型转换实例分析
Apr 25 Javascript
jquery过滤特殊字符',防sql注入的实现方法
Aug 17 Javascript
在iframe中使bootstrap的模态框在父页面弹出问题
Aug 07 Javascript
Vue.js 踩坑记之双向绑定
May 03 Javascript
微信小程序Flex布局用法深入浅出分析
Apr 25 Javascript
vue中使用 pako.js 解密 gzip加密字符串的方法
Jun 10 Javascript
微信小程序实现时间戳格式转换
Jul 20 Javascript
理解Javascript_11_constructor实现原理
Oct 18 #Javascript
关于js中window.location.href,location.href,parent.location.href,top.location.href的用法与区别
Oct 18 #Javascript
jQuery Validation实例代码 让验证变得如此容易
Oct 18 #Javascript
jQuery 验证插件 Web前端设计模式(asp.net)
Oct 17 #Javascript
基本jquery的控制tabs打开的数量的代码
Oct 17 #Javascript
Javascript表达式中连续的 &amp;&amp; 和 || 之赋值区别
Oct 17 #Javascript
Javascript读取cookie函数代码
Oct 16 #Javascript
You might like
PHP生成网页快照 不用COM不用扩展.
2010/02/11 PHP
PHP中文件读、写、删的操作(PHP中对文件和目录操作)
2012/03/06 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
Yii2中DropDownList简单用法示例
2016/07/18 PHP
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
2011/01/08 Javascript
JS+CSS实现实用的单击输入框弹出选择框的方法
2015/02/28 Javascript
jQuery实现Email邮箱地址自动补全功能代码
2015/11/03 Javascript
AngularJs 60分钟入门基础教程
2016/04/03 Javascript
jQuery插件EasyUI实现Layout框架页面中弹出窗体到最顶层效果(穿越iframe)
2016/08/05 Javascript
微信小程序用户信息encryptedData详解
2018/08/24 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
利用Vue-draggable组件实现Vue项目中表格内容的拖拽排序
2019/06/07 Javascript
如何管理Vue中的缓存页面
2021/02/06 Vue.js
[05:06]DOTA2-DPC中国联赛 正赛 VG vs Magma选手采访
2021/03/11 DOTA
详解Python的Lambda函数与排序
2016/10/25 Python
Python实现二分查找与bisect模块详解
2017/01/13 Python
Python数据分析之如何利用pandas查询数据示例代码
2017/09/01 Python
Python内置模块hashlib、hmac与uuid用法分析
2018/02/12 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
Python+threading模块对单个接口进行并发测试
2019/06/25 Python
python多线程共享变量的使用和效率方法
2019/07/16 Python
Python 仅获取响应头, 不获取实体的实例
2019/08/21 Python
python实现截取屏幕保存文件,删除N天前截图的例子
2019/08/27 Python
python 实现多线程下载视频的代码
2019/11/15 Python
IronPython连接MySQL的方法步骤
2019/12/27 Python
pycharm实现在子类中添加一个父类没有的属性
2020/03/12 Python
python IDLE添加行号显示教程
2020/04/25 Python
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
中间件分为哪几类
2012/03/14 面试题
房地产财务部员工岗位职责
2014/03/12 职场文书
《风筝》教学反思
2014/04/10 职场文书
实习工作表现评语
2014/12/31 职场文书
2015年除四害工作总结
2015/07/23 职场文书
2016公务员年度考核评语
2015/12/01 职场文书
CSS巧用渐变实现高级感背景光动画
2021/12/06 HTML / CSS
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技