javascript代码运行机制简单介绍
本文将通过一个简单的代码实例介绍一下javascript引擎对代码从定义到执行的相关过程,从而加深对作用域作用域链等概念的理解。
在阅读本文之前最好参阅以下几篇文章:
(1).执行上下文可以参阅javascript执行上下文详解一章节。
(2).变量对象可以参阅javascript变量对象详解一章节。
(3).作用域和作用域链可以参阅javascript 作用域和作用域链详解一章节。
以下面的代码为例子做一下介绍:
var x = 1;//定义全局变量x,并赋值为1 function wrap(y){//定义一个全局函数 var x = 2;//定义一个局部变量,并赋值为2 function inner(z){//定义一个局部函数 console.log(x+y+z);//输出值 } return inner;//返回内部函数 } var f = wrap(3);//将返回的内部函数赋值给变量f f(1);//调用函数
上面的代码是一个典型的闭包的引用,关于闭包可以参阅javascript闭包概念介绍一章节。
第一阶段:
首先会创建一个全局对象,它的属性或者方法可访问性也是全局的。
全局对象具有唯一性,并且生命周期会伴随整个应用程序。
全局对象创建时,Math,String,Date和document等对象作为其属性存在。
全局对象通常只能够使用别名来访问,比如在web中就是用window来访问全局对象,可以用伪代码表示如下:
//创建一个全局对象 var global = { Math:{}, String:{}, Date:{}, document:{}, //其他属性 window:this }
这个时候,javascript还会构建一个执行环境栈( Execution Context Stack) 。
与此同时,全局执行环境上下文Execution Context(EC)也会被创建,并将其压入执行环境栈中。
执行环境栈的创建目的是为了保证代码能够按照正确的顺序执行。
全局执行环境上下文中还会生一个变量对象(Varibale Object) VO,并把VO指向全局对象。
VO包含全局对象中固有的一些属性,比如Math,String,Date和document等,也包含自定义的函数或者变量。
函数在声明的同时为其创建一个[[Scope]]内部属性,表示如下:
wrap.[[Scope]] = [ globalContext.VO ];
此时执行环境栈可以用伪代码表示如下:
ECStack = [ //执行环境栈 EC(G) = { //全局执行环境上下文 VO(G):{ //全局变量对象 ... //包含全局对象原有的属性 x = 1; //定义变量x wrap = function(){}; //定义函数wrap A[[scope]] = [globalContext.VO]; } } ];
第二阶段:
当调用wrap()函数之后,会创建一个函数执行上下文,并将这个执行上下文压入执行环境栈的顶部。
此时执行环境栈中有两个执行环境上下文,分别是全局执行环境上下文和函数wrap执行环境上下文。
wrap的执行环境上下文在栈顶,全局执行环境上下文在栈的底部。
函数执行上下文中也会建立变量对象(Varibale Object) VO,不过函数的变量对象通常称之为活动对象(Activation Object) A0。活动对象A0包含函数的形参、arguments对象、this对象、以及局部变量和内部函数的定义。
当执行环境上下文被创建时 ,函数wrap的作用域链(Scope Chain)就会被建立 ,用于标识符解析。
作用域链(Scope Chain)= 当前VO+A[[scope]]。
此时的ECStack结构:
ECStack = [ //执行环境栈 EC(wrap) = { //A的执行环境 [scope]:VO(G), //VO是全局变量对象 AO(wrap) : { //创建函数wrap的活动对象 y:3, x:2, //定义局部变量x inner:function(){}, //定义函数B A[[scope]]:[globalContext.VO]; arguments:[],//在函数中访问的arguments就是AO中的arguments this:window }, scopeChain:[ wrapContext.AO,//wrap函数变量对象 globalContext.VO//全局变量对象 ] }, EC(G) = { //全局执行环境上下文 VO(G):{ //全局变量对象 ... //包含全局对象原有的属性 x = 1; //定义变量x wrap = function(){}; //定义函数wrap A[[scope]] = [globalContext.VO]; } } ];
对于内部函数执行也是同样的道理,这里就不多介绍了。
javascript代码运行机制简单介绍,这样的场景在实际项目中还是用的比较多的,关于javascript代码运行机制简单介绍就介绍到这了。
javascript代码运行机制简单介绍属于前端实例代码,有关更多实例代码大家可以查看。