执行上下文
什么是执行栈?
执行栈是管理代码运行时产生的一系列执行上下文,它遵循 LIFO(LAST IN FIRST OUT 后进先出)原则来保证代码有序的运行。
执行上下文一般分文三种: 1.全局执行上下文 2.函数执行上下文
2.evel 执行上下文(一般不推荐使用)
当程序开始运行时全局执行上下文会压入执行栈的底部,遇到可函数执行时就创建函数执行上下文继续压入栈,执行完毕时就出栈。下面举个栗子:
function c() {
console.log('c');
}
function b() {
console.log('b');
c();
}
function a() {
console.log('a');
b();
}
a();
试着想一下这段代码的执行过程,我们用 ECstack 模拟执行栈的过程,在 ECstack 的底部总是会有一个全局的执行上下文,所以最初的执行栈张这样
ECstack = [gloabcontext];
我们按上面描述的当遇到可执行函数就创建对应的上下文压入栈底,遵循后进先出原则出栈
//当执行函数a时,创建执行上下文压入栈底
ECstack.push(<fun> a)
//在a里又执行了函数b,就紧接着创建b的执行上下文压入栈底
ECstack.push(<fun> b)
//最后在b里又又执行c函数,再次创建c的执行上下文压入栈底
ECstack.push(<fun> c)
//到c 可算没有了, 我们遵循后进先出原则依次执行完出栈
ECstack.pop() //c出栈
ECstack.pop()//b出栈
ECstack.pop()//a出栈
在举个栗子:
function a() {
var value = 'local scope';
function b() {
console.log(value);
}
return b();
}
a();
function a() {
var value = 'local scope';
function b() {
console.log(value);
}
return b;
}
a()();
咋一看两段代码其实差不多,但是他的执行过程是不一样的,为了更好的理解执行栈我们来分析下这两端代码的执行过程
第一段代码
//a()执行的时候,创建执行上下文入栈
ECsatck.push(<fun> a)
//函数a遇到b可执行函数,执行b函数创建可执行上下文入栈
ECstack.push(<fun> b)
//后进先出原则b执行完出栈
ECstack.pop()
//a执行完出栈
ECstack.pop()
第二段代码
//a()执行的时候,创建执行上下文入栈
ECsatck.push(<fun> a)
// a执行完后返回了b函数,注意这里没有直接执行而是直接返回了b,所有没有创建b函数的上下文,a执行完直接出栈
ECstack.pop() //a出栈
//在外部返回的b函数被执行, 创建b的执行上下文,压入栈,
ECstack.push(<fun> b)
//b执行完出栈
ECstack.pop()