Execution Context(执行上下文)

在这一部分我们将会提及js中的一些执行上下文(execution context),还有与执行上下文中相关联的可执行代码(executable code).

Execution Context是通过ECMA 262 规范用于Exectuable code的类型和区分的抽象概念。该标准并没有从技术角度明确定义Execution Context的种类和结构,该问题需要js引擎去实现。

从逻辑上讲,执行上下文将会形成一个stack, stack的底部始终是global context,stack顶部总是当前active exection context 。每当进入或者退出执行上下文,这个stack就会被修改(pushed or popped)。

Execution Context(执行上下文)_第1张图片
我们将执行上下文定义成一个数组:
ExecutionContextStack = [];

1.每当加载外部的js文件时,或者进入标签时,就会创建一个全局执行上下文;
当程序开始时,ECStack为:
ECStack = [
globalContext
]

2.每当调用一个function时,就会创建一个functionContext,但是并不包括内部函数的执行上下文或者递归调用的上下文,以下面代码为例:

(function f(flag){
	if(flag){
		return;
	}
	f(true);
})(false);

接着ECStack就会发生变化:

1.当进入函数f时
ECStack = [
 functioncontext
globalContext
]
2.当递归调用自身时
ECStack = [
 functioncontext -> 递归调用
 functioncontext
globalContext
]
函数可以被重复调用,故一个函数可能会产生多个执行上下文
function fn(a){
}
fn(1);
fn(2);
fn(3);
以上都是调用同一个函数,但是会产生三个执行上下文,并且三个执行上下文是有所不同的,其中变量对象中的arguments就不同,下一篇会有所说明

每当函数内部遇到return或者执行完毕时,当前的执行上下文就会从stack中退出,最后ECStack就剩下全局上下文了。那么什么时候全局上下文也从stack中退出呢?当你退出整个程序(关闭文件)全局上下文就会从stack中退出。
举个例子说明上述的过程:

var a = 10;
function sayHello(){
console.log('hello')
}
sayHello()

1.第一步进入js代码时,全局上下文就会被创建,该上下文会被推入到ECStack中;第二步当调用sayHello函数时,就会创建一个sayHello函数上下文,并将该上下文推入到ECStack中;如下图:
Execution Context(执行上下文)_第2张图片2.当sayHello函数的内部代码执行完毕时,该函数上下文就会从ECStack中退出,此时ECStack中就剩下全局上下文了;当关闭文件时,全局上下文就会从ECStack中退出;
Execution Context(执行上下文)_第3张图片
每一个执行上下文都可看成是一个对象,都会有一些特定的属性,至少包含三个值,variable object,scope chain ,this value。
Execution Context(执行上下文)_第4张图片
下一篇会写执行环境中的变量对象部分

你可能感兴趣的:(js)