深入理解JavaScript中的执行上下文(Execution Contexts) 执行环境

213 1 年前
什么是执行上下文?什么是执行环境?以前并不是清楚,今天查阅了很多文章,看是明白了一点,在此记录下来,方便以后查阅温习。

执行上下文(Execution Contexts简称-EC)是ECMA-262标准里的一个抽象概念,用于同可执行代码(executable code)概念进行区分。

说白了,执行上下文就是 执行环境

每次当控制器转到ECMAScript可执行代码的时候,就会进入到一个执行上下文。

可执行代码

在javascript中可可执行代码的类型有三种:全局代码、函数代码、eval代码

全局代码(Global code)

这种类型的代码是在"程序"级处理的:例如加载外部的js文件或者本地<script></script>标签内的代码。全局代码不包括任何function体内的代码。 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境。

函数代码(Function code)

任何一个函数体内的代码,但是需要注意的是,具体的函数体内的代码是不包括内部函数的代码。

Eval代码(Eval code)

eval内部的代码

执行上下文栈(Execution context stack,ECS)

JS解释器被实现为单线程,这也就意味着同一时间只能发生一件事情,其他的行为或事件将会被放在叫做执行栈里面排队

为了模拟执行上下文栈的行为,让我们定义执行上下文栈是一个数组:

ECStack = [];

当浏览器首次载入脚本,它将默认进入全局执行上下文。会向执行上下文栈压入一个全局执行上下文,我们用 globalContext 表示它,并且只有当整个应用程序结束的时候,ECStack 才会被清空,所以程序结束之前, ECStack 最底部永远有个 globalContext:

ECStack = [
    globalContext
];

如果,你在你的全局代码中调用一个函数,你程序的时序将进入被调用的函数,并创建一个新的执行上下文,并将新创建的上下文压入执行栈的顶部。

function fun3() {
    console.log('fun3')
}

function fun2() {
    fun3();
}

function fun1() {
    fun2();
}

fun1();

当执行一个函数的时候,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。知道了这样的工作原理,让我们来看看如何处理上面这段代码:

// fun1()
ECStack.push(<fun1> functionContext);

// fun1中竟然调用了fun2,还要创建fun2的执行上下文
ECStack.push(<fun2> functionContext);

// 擦,fun2还调用了fun3!
ECStack.push(<fun3> functionContext);

// fun3执行完毕
ECStack.pop();

// fun2执行完毕
ECStack.pop();

// fun1执行完毕
ECStack.pop();

// javascript接着执行下面的代码,但是ECStack底层永远有个globalContext

如果调用当前函数内部的其他函数,相同的事情会在此上演。代码的执行流程进入内部函数,创建一个新的执行上下文并把它压入执行栈的顶部。浏览器总会执行位于栈顶的执行上下文,一旦当前上下文函数执行结束,它将被从栈顶弹出,并将上下文控制权交给下一个的顶栈。这样,堆栈中的上下文就会被依次执行并且弹出堆栈,直到回到全局的上下文。

分类栏目
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6