在这一部分咱们将会说起js中的一些执行上下文(execution context),还有与执行上下文中相关联的可执行代码(executable code).数组
Execution Context是经过ECMA 262 规范用于Exectuable code的类型和区分的抽象概念。该标准并无从技术角度明肯定义Execution Context的种类和结构,该问题须要js引擎去实现。bash
从逻辑上讲,执行上下文将会造成一个stack, stack的底部始终是global context,stack顶部老是当前active exection context 。每当进入或者退出执行上下文,这个stack就会被修改(pushed or popped)。函数
1.每当加载外部的js文件时,或者进入<script></script>
标签时,就会建立一个全局执行上下文; 当程序开始时,ECStack为: ECStack = [ globalContext ]ui
2.每当调用一个function时,就会建立一个functionContext,可是并不包括内部函数的执行上下文或者递归调用的上下文,如下面代码为例:this
(function f(flag){
if(flag){
return;
}
f(true);
})(false);
复制代码
接着ECStack就会发生变化:spa
1.当进入函数f时
ECStack = [
<f> functioncontext
globalContext
]
2.当递归调用自身时
ECStack = [
<f> functioncontext -> 递归调用
<f> functioncontext
globalContext
]
复制代码
函数能够被重复调用,故一个函数可能会产生多个执行上下文
function fn(a){
}
fn(1);
fn(2);
fn(3);
以上都是调用同一个函数,可是会产生三个执行上下文,而且三个执行上下文是有所不一样的,其中变量对象中的arguments就不一样,下一篇会有所说明
复制代码
每当函数内部遇到return或者执行完毕时,当前的执行上下文就会从stack中退出,最后ECStack就剩下全局上下文了。那么何时全局上下文也从stack中退出呢?当你退出整个程序(关闭文件)全局上下文就会从stack中退出。 举个例子说明上述的过程:code
var a = 10;
function sayHello(){
console.log('hello')
}
sayHello()
复制代码
1.第一步进入js代码时,全局上下文就会被建立,该上下文会被推入到ECStack中;第二步当调用sayHello函数时,就会建立一个sayHello函数上下文,并将该上下文推入到ECStack中;以下图: cdn
下一篇将会讲执行上下文中的Variab Object对象