理解执行栈 和执行上下文

141 阅读2分钟

理解执行栈 和执行上下文

执行上下文(执行上下文环境)

​ 一句话简单概括:就是代码执行前的准备工作,也叫执行上下文环境。

运行javascript 代码时,当代码执行进入一个环境时,就会为当前环境创建一个执行上下文,他会在代码运行前做一些准备工作:创建变量(v o),改变this 指向,确定作用域链等。

javascript 中的执行环境
  • 全局环境
  • 函数环境
  • eval 环境(已经不推荐使用)

那么与之对应的执行上下文也有三种:

  • 全局执行上下文

  • 函数执行上下文

  • eval 执行上下文

    栈数据结构

遵循先进后出,后进先出的原则,或者LIFO(Last In First Out)规则。

最先出去的永远是栈顶的数据

image-20240515191123013

执行栈

理解完栈,接着分析JavaScript 中如何通过栈来管理多个执行上下文。

程序执行进入一个执行环境时,他的上下文就会被创建,并被推入执行栈中(入栈),程序执行完成时,它的执行上下文就会被销毁,并从栈顶被推出(出栈),控制权交给下一个执行上下文。

因为javascript在执行代码时最先进入全局环境,所以处于最底部的永远是全局环境的执行上下文,而处于栈顶的则是当前正在执行函数的执行上下文。

var a=1;
var b= far
console.log(b)
console.log(far)
function far(){
  var c=2
  console.log(c)
  console.log(a)
}
b()

--- 创建全局上下文环境
		Vo阶段(Variable Object)
    vo={
      a:undefined,
      b:function far,
      far:function far
    }
		改变当前this指向;
    确定当前作用域链
     
   代码执行......
   
   当代码运行到b()时:
	---创建函数执行上下文
	   vo={
       c:undefined
     },
    改变当前this指向;
    确定当前作用域链;
		
		代码执行.....
    
   	当代码执行到  console.log(a) 时,
    从当前vo 中无法拿到a,于是向全局上下文环境中的vo去查找

image-20240515175616433 下面来具体看一段具体的代码示例:

function foo(){
  function bar(){
    return 'I am boy'
  }
  return bar()
}

对应图解如下:

image-20240515195309063

执行上下文的数量限制(堆栈溢出)

执行上下文可存在多个,虽然没有明确的数量限制,但是如果超出了栈分配的空间,就会造成堆栈溢出,常见于递归调用,没有终止条件造成死循环的场景