学习JavaScript,对于JavaScript的执行原理,是必须要了解的,因此为大家讲解一下Javascript的执行上下文和执行栈:
1、执行上下文是什么
简而言之,执行上下文是评估和执行 JavaScript 代码环境的抽象概念。每当 Javascript 代码在运行的时候,它都是在执行上下文中运行。
2、执行上下文的类型
(1)全局执行上下文----任何不在函数内部的代码都在全局执行上下文中,全局执行上下文执行俩件事:创建全局的window对象,并设置thie的值是这个全局对象,一个程序中只会有一个全局上下文。
(2)函数执行上下文——每当一个函数被调用的时候,就会为这个函数创建一个函数执行上下文,函数上下文会有多个。其执行顺序为先进后出。
(3)eval函数执行上下文———执行在eval函数内部的代码也会为自己创建一个自己的执行上下文。
3、执行栈是什么
执行栈就是用来存储代码运行时创建的所有执行上下文。顺序是后进先出,当JS引擎开始执行代码的时候,首选会先创建一个全局的执行上下文,并压入执行栈中,当遇到被调用的函数时,会创建一个函数执行上下文,并压入到执行栈中。当函数执行结束之后,会从执行上下文栈中弹出。
例子:
let str=“hello world”
function test1 () {
test2()
console.log(‘this is test1!’)
}
function test2 () {
console.log(“this is test2”)
}
test1()
function test3 () {
console.log(“this is test3”)
}
test3()
当js引擎执行上面的代码的时:
(1)首先会创建全局执行上下文
(2)创建test1的函数执行上下文
(3)创建test2函数执行上下文
(4)弹出test2函数执行上下文
(5)创建test3函数执行上下文
(6)弹出test3函数执行上下文
(7)弹出全局执行上下文
4、如何创建执行上下文
创建执行上下文分为两个阶段:创建阶段和执行阶段
创建阶段:
(1)this的值是什么
在全局执行上下文中,this指向的是全局,即window
在函数执行上下文中,看函数的调用方式,如果被一个对象调用,那this指向这个对象,反之指向window
(2)创建词法环境组件
词法环境是一种规范类型,基于 ECMAScript 代码的词法嵌套结构来定义标识符和具体变量和函数的关联。一个词法环境由环境记录器和一个可能的引用外部词法环境的空值组成。简单来说词法环境是一种持有标识符—变量映射的结构。词法环境内部包括俩个组件:环境记录器和外部环境的引用。
- 环境记录器是存储变量和函数声明的实际位置。
- 外部环境的引用意味着它可以访问其父级词法环境(作用域)。
词法环境类型:
在全局环境中,环境记录器是对象环境记录器。
在函数环境中,环境记录器是声明式环境记录器。
注意 — 对于函数环境,声明式环境记录器还包含了一个传递给函数的 arguments 对象(此对象存储索引和参数的映射)和传递给函数的参数的 length。
(3)创建变量环境组件
它同样是一个词法环境,其环境记录器持有变量声明语句在执行上下文中创建的绑定关系。
在 ES6 中,词法环境组件和变量环境的一个不同就是前者被用来存储函数声明和变量(let 和 const)绑定,而后者只用来存储 var 变量绑定。
执行阶段
在此阶段,完成对所有这些变量的分配,最后执行代码。
注意 — 在执行阶段,如果 JavaScript 引擎不能在源码中声明的实际位置找到 let 变量的值,它会被赋值为 undefined。