javascript 执行上下文与调用栈

概念

执行上下文:js执行一段代码时的运行环境。

调用栈:是一种用来管理函数之间调用关系的数据结构。

执行上下文

在执行一段代码时,会做一些准备工作,代码先进行编译后执行,编译的时候就会产生可执行代码与执行上下文。
词法分析->语法分析->代码生成

创建执行上下文的三种情况:
1.执行全局代码时,会生成全局上下文,整个页面的生命周期内,全局上下文唯一
2.函数被调用时,函数体内的代码会被编译,创建函数执行上下文,无闭包的话使用完之后就被销毁
3.eval被执行时,eval内的代码被编译,创建执行上下文

执行上下文包含的属性

1.变量环境组件: 指定一个词法环境对象,其环境数据用于保存由该执行环境内的代码通过var 与 functionDeclartion创建的绑定
2.词法环境组件:指定一个词法环境对象,用于解析该执行环境内的代码创建的标识符引用;
3.this :指定该环境this关键字关联的值

每个词法环境对象包含2部分:
环境记录器
外部环境的引用(全局词法环境为空)

环境记录器
环境记录器分为两种:
1)声明式环境记录器
存在于函数作用域中,存储变量、函数、参数。
2)对象式环境记录器
存在于全局作用域和块级作用域中,存储变量、函数

外部环境引用
如果在当前环境内找不到变量,引擎可以通过引用在外部环境继续查找

其中执行环境的词法环境和变量环境组件始终为词法环境对象。当创建一个执行环境时,其词法环境组件和变量环境组件最初是同一个值。在该执行环境相关联的代码的执行过程中,变量环境组件永远不变,而词法环境组件有可能改变

词法环境中,进入或者退出一个块级作用域,里面的数据都会改变

区别是:
let、const声明的变量,外部环境引用保存在词法环境组件中。
var和function声明的变量,外部环境引用保存在环境变量组件中

如何管理执行上下文?

创建一个执行上下文栈(Execution context stack, ECS),又称调用栈

JavaScript引擎使用栈的结构来管理执行上下文

1
2
3
4
5
6
7
8
9
10
var a = 2
function add(b,c){
return b+c
}
function addAll(b,c){
var d = 10
result = add(b,c)
return a+result+d
}
addAll(3,6)

第一步: 代码编译,创建全局上下文,并将其压入栈底

第二步: 调用addAll函数,编译addAll函数并创建函数执行上下文,将它压入栈中

第三步: 执行addAll函数,到add函数时,编译add函数并创建执行上下文,压入栈中

第四部:执行add函数,返回结果,将add函数弹出栈

第五步:addAll函数中拿到result结果,返回结果,将addAll上下文也弹出

第六步: 返回结果,执行完毕

栈溢出

栈的最大容量和深度都是有限制的,超出限制,就会抛出错误

1
Maximum call stack size exceeded

思考

1.什么是执行上下文,它包含了哪些属性?
2.变量环境与词法环境的相同点与差异点?


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!