js执行上下文 一,执行上下文的类型 二,执行上下文的生命周期

执行上下文(Execution Context):函数执行前进行的准备工作(也称执行上下文环境)。

当执行代码进入一个环境时,就会为该环境创建一个执行上下文,它会做一些准备工作,如变量提升,确定作用域等。


一,执行上下文的类型

js中有三种执行上下文类型:

全局执行上下文:顶层上下文,任何不在函数内部的代码都在其中。上下文中的大哥大!它干了两件事:1.创建一个全局的window对象(浏览器环境下),2.设置this的值等于这个全局对象。(一个程序中只会有一个全局执行上下文)

函数执行上下文:函数被调用时,会创建新的上下文,可以有多个。

Eval函数执行上下文:aval函数专用,用的不多,没排面,不讨论。

执行栈

在js中,通过栈的存取方式来管理执行上下文,我们可称其为执行栈,或函数调用栈(Call Stack)。

栈遵循“先进先出,后进后出”的规则,也就是LIFO(Last In First Out)规则,可以用乒乓球盒子来类比理解。

特点:

1,先进先出,后进后出

2,出口在顶部,且仅有一个

当js引擎第一次遇到你的脚本时,它会创建一个全局的执行上下文并且压入当前执行栈。而每当引擎遇到一个函数调用,它会为该函数创建一个新的执行上下文并压入栈的顶部。

引擎会执行那些位于执行上下文顶栈顶的函数,当函数执行结束时,其执行上下文从栈中弹出,控制流程达到当前栈中的下一个上下文。

我们可以通过示例代码来理解:


function foo () {

   function bar () {

       return 'I am bar';

   }

   return bar();

}

foo();

二,执行上下文的生命周期

执行上下文的生命周期有两个阶段:

创建阶段(进入执行上下文,如:变量提升等)

执行阶段

创建阶段的操作:

1,创建变量对象

函数环境会初始化创建Arguments对象(并赋值),并传递长度length

匿名函数声明(并赋值)

1,变量声明,函数表达式声明(未赋值,即变量提升)

2,确定this指向(this由调用者确定)

3,确定作用域(词法环境确定,哪里声明,哪里确定)

执行阶段的操作

1,变量对象赋值

变量赋值

函数表达式赋值

2,调用函数

3,执行其他代码片段

值得注意的是,执行上下文可存在多个,因此在递归中可能因为没有终止条件而造成死循环,堆栈溢出错误。

// 递归调用自身

function foo() {

 foo();

}

foo();

// 报错: Uncaught RangeError: Maximum call stack size exceeded

文末总结:

1,js是单线程

2,栈顶的执行上下文处于执行中时,其他的需要排队

3,处于底部的总是全局上下文,关闭页面时出栈

4,函数执行上下文可存在多个,但应避免递归时堆栈溢出

5,函数调用时就会创建新的上下文,即使调用自身,同样如此

参考文档:

https://mp.weixin.qq.com/s/lAvyjfBZvX0E50QiW3aW7w

https://juejin.im/post/5ba32171f265da0ab719a6d7(并未讨论其中的词法环境)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章