this对象的理解及JavaScript中执行上下文和执行栈是什么?( 三 )


举个例子
let a = 20;const b = 30;var c;function multiply(e, f) {var g = 20;return e * f * g;}c = multiply(20, 30);执行上下文如下:
GlobalExectionContext = {ThisBinding: <Global Object>,LexicalEnvironment: {// 词法环境EnvironmentRecord: {Type: "Object",// 标识符绑定在这里a: < uninitialized >,b: < uninitialized >,multiply: < func >}outer: <null>},VariableEnvironment: {// 变量环境EnvironmentRecord: {Type: "Object",// 标识符绑定在这里c: undefined,}outer: <null>}}FunctionExectionContext = {ThisBinding: <Global Object>,LexicalEnvironment: {EnvironmentRecord: {Type: "Declarative",// 标识符绑定在这里Arguments: {0: 20, 1: 30, length: 2},},outer: <GlobalLexicalEnvironment>},VariableEnvironment: {EnvironmentRecord: {Type: "Declarative",// 标识符绑定在这里g: undefined},outer: <GlobalLexicalEnvironment>}}留意上面的代码,let和const定义的变量a和b在创建阶段没有被赋值,但var声明的变量从在创建阶段被赋值为undefined
这是因为,创建阶段,会在代码中扫描变量和函数声明,然后将函数声明存储在环境中
但变量会被初始化为undefined(var声明的情况下)和保持uninitialized(未初始化状态)(使用let和const声明的情况下)
这就是变量提升的实际原因
执行阶段在这阶段,执行变量赋值、代码执行
如果 Javascript 引擎在源代码中声明的实际位置找不到变量的值,那么将为其分配 undefined 值
回收阶段执行上下文出栈等待虚拟机回收执行上下文
执行栈执行栈,也叫调用栈,具有 LIFO(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文

this对象的理解及JavaScript中执行上下文和执行栈是什么?

文章插图
 
当Javascript引擎开始执行你第一行脚本代码的时候,它就会创建一个全局执行上下文然后将它压到执行栈中
每当引擎碰到一个函数的时候,它就会创建一个函数执行上下文,然后将这个执行上下文压到执行栈中
引擎会执行位于执行栈栈顶的执行上下文(一般是函数执行上下文),当该函数执行结束后,对应的执行上下文就会被弹出,然后控制流程到达执行栈的下一个执行上下文
举个例子:
let a = 'Hello World!';function first() {console.log('Inside first function');second();console.log('Again inside first function');}function second() {console.log('Inside second function');}first();console.log('Inside Global Execution Context');转化成图的形式
this对象的理解及JavaScript中执行上下文和执行栈是什么?

文章插图
 
简单分析一下流程:
  • 创建全局上下文请压入执行栈
  • first函数被调用,创建函数执行上下文并压入栈
  • 执行first函数过程遇到second函数,再创建一个函数执行上下文并压入栈
  • second函数执行完毕,对应的函数执行上下文被推出执行栈,执行下一个执行上下文first函数
  • first函数执行完毕,对应的函数执行上下文也被推出栈中,然后执行全局上下文
  • 所有代码执行完毕,全局上下文也会被推出栈中,程序结束




推荐阅读