理解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 相关文章推荐
JavaScript 判断日期格式是否正确的实现代码
Jul 04 Javascript
jQuery使用一个按钮控制图片的伸缩实现思路
Apr 19 Javascript
JavaScript阻止浏览器返回按钮的方法
Mar 18 Javascript
JavaScript中的getDay()方法使用详解
Jun 09 Javascript
SWFObject基本用法实例分析
Jul 20 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
Jul 05 Javascript
js+html5实现半透明遮罩层弹框效果
Aug 24 Javascript
node实现定时发送邮件的示例代码
Aug 26 Javascript
Angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法
Oct 24 Javascript
浅谈vue单一组件下动态修改数据时的全部重渲染
Mar 01 Javascript
es6中new.target的作用和使用场景简单示例分析
Mar 14 Javascript
关于Node.js中频繁修改代码重启服务器的问题
Oct 15 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 rawurlencode与urlencode函数的深入分析
2013/06/08 PHP
Laravel 5框架学习之子视图和表单复用
2015/04/09 PHP
php foreach如何跳出两层循环(详解)
2016/11/05 PHP
php实现银联商务公众号+服务窗支付的示例代码
2019/10/12 PHP
msn上的tab功能Firefox对childNodes处理的一个BUG
2008/01/21 Javascript
Extjs TriggerField在弹出窗口显示不出问题的解决方法
2010/01/08 Javascript
js word表格动态添加代码
2010/06/07 Javascript
浅析JavaScript中的typeof运算符
2013/11/30 Javascript
JavaScript中rem布局在react中的应用
2015/12/09 Javascript
JS动态改变浏览器标题的方法
2016/04/06 Javascript
jquery实现简单Tab切换菜单效果
2020/07/17 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
javascript计算对象长度的方法
2017/10/25 Javascript
详解Webpack + ES6 最新环境搭建与配置
2018/06/04 Javascript
在移动端使用vue-router和keep-alive的方法示例
2018/12/02 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
js实现拖动缓动效果
2020/01/13 Javascript
vue.js iview打包上线后字体图标不显示解决办法
2020/01/20 Javascript
vue跳转页面的几种方法(推荐)
2020/03/26 Javascript
vue项目中自定义video视频控制条的实现代码
2020/04/26 Javascript
SpringBoot+Vue开发之Login校验规则、实现登录和重置事件
2020/10/19 Javascript
[01:05:24]Ti4 冒泡赛第二天 iG vs NEWBEE 3
2014/07/15 DOTA
Python库urllib与urllib2主要区别分析
2014/07/13 Python
python实现简单socket程序在两台电脑之间传输消息的方法
2015/03/13 Python
python机器学习之神经网络(二)
2017/12/20 Python
Python3.5实现的罗马数字转换成整数功能示例
2019/02/25 Python
python实现连连看辅助(图像识别)
2020/03/25 Python
pandas to_excel 添加颜色操作
2020/07/14 Python
CSS3+font字体文件实现圆形半透明菜单具体步骤(图解)
2013/06/03 HTML / CSS
美国知名的网上鞋类及相关服装零售商:Shoes.com
2017/05/06 全球购物
群众路线领导班子整改方案
2014/10/25 职场文书
党员志愿者服务倡议书
2015/04/29 职场文书
同事打架检讨书
2015/05/06 职场文书
卫生院义诊活动总结
2015/05/07 职场文书
2016年艾滋病宣传活动总结
2016/04/01 职场文书
适合后台管理系统开发的12个前端框架(小结)
2021/06/29 Javascript