2020/12/18 执行上下文和上下文栈

执行上下文:
js得可执行代码,有以下三类:全局代码,函数代码,eval代码。当js 引擎遇到这三种代码时,会开始工作,创建执行上下文。执行上下文得生名周期有俩个阶段:准备阶段和代码执行阶段,在准备阶段,会做三件事,即用arguments创建当前执行上下文得活动对象,确定当前执行上下文得作用域链和绑定当前执行上下文得this属性。
1:作用域链 scope
2: 变量对象 AO GO (预编译)
3:this
执行上下文(Execution context 简称 EC)
js 是单线程得 ,运行在全局EC 每进入一个 function 就做一次入栈操作,然后向栈顶压入一个该属性function 得新得EC,如果function 中又调用了另一个function 则 在执行依次入栈。。。。。依次执行完在依次出栈,回到全局EC 。全局EC一定在栈底,浏览器关闭后出栈。

执行上下文栈:
js代码执行顺序是什么,大部分人都知道同步执行

var foo = function(){
            console.log('foo1');
        }
        foo(); // foo1
        var foo = function(){
            console.log('foo2');
        }
        foo() // foo2

看完之后比较下面得代码

function foo(){
            console.log('foo1');0
        }

        foo();// foo2
        function foo(){
            console.log('foo2');
        }
        foo() // foo2

js 引擎 执行是一段一段得解析得 ;不是一行一行得解析得 当一段代码执行完毕后 ,会进行一个准备工作,
比如:第一个列子,变量提升,第二个列子:函数声明提升

而这个准备工作就是: 变量提升,和函数提升

现在思考一个问题,写了这么多得函数,去哪里了 怎么管理创建得那么多执行上下文呢?
所以js 引擎创建了执行上下文栈来管理执行上下文
为了模拟执行上下文栈得行为,我们来定义执行上下文栈式一个数组

ECStack = [];+

假设当js 开始要解释执行代码得时候,最先遇到得就是 全局代码,所以初始化得时候首先就会 向下 执行上下文栈 添加一个全局执行上下文,我们用 gobal context 表示它 并且当整个应用程序结束得时候 ECStack 才会被清空 ,所以程序结束之前 ,ecstack 最底部 永远有个 globaltext

// 模拟将全局执行上下文添加到执行上下文栈中
ECStack = [
    globalContext
];

现在js 引擎 遇到下面的这段代码:

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

function foo2() {
    foo3();
}

function foo1() {
    foo2();
}

foo1();

当执行一个函数的时候,就会创建一个执行上下文,并且添加执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。 这就是 工作原理。

// 模拟js引擎执行代码

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

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

// foo2还调用了foo3!创建 foo3执行上下文
ECStack.push(<foo3> functionContext);
// ECStack= [globalContext,foo1<functionCountext>,foo2<functionCountext>,foo3<funcrtionCountext>]

// foo3执行完毕 foo3执行上下文销毁
ECStack.pop(); 
// ECStack= [globalContext,foo1<functionCountext>,foo2<functionCountext>]

// foo2执行完毕 foo2执行上下文销毁 
ECStack.pop(); 
// ECStack= [globalContext,foo1<functionCountext>]

// foo1执行完毕,foo1执行上下文销毁
ECStack.pop();
// ECStack= [globalContext]


// javascript接着执行下面的代码,但是ECStack底层永远有个globalContext
// 关闭浏览器 关闭应用程序
// ECStack.pop()
// ECStack = []
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值