Javascript中执行上下文和执行环境

什么是执行上下文?

js代码解析执行时所处的环境,顾名思义。

全局执行上下文

只有一个,浏览器中全局对象就是window对象,this指向全局对象

函数执行上下文

只有函数被调用时才会创建执行环境,可以有多个,多次。

eval执行上下文

js中不推荐用这个函数

执行栈

栈的结构,后进先出。先会创建一个全局的执行上下文,push到当前的执行栈顶,当调用新的函数则push新的函数执行上下文,当执行完后pop出执行栈。

执行上下文的创建过程

两个阶段创建阶段和执行阶段

创建阶段

确定this指向

全局执行上下文中,this指向全局
函数执行上下文中,this指向取决于当前调用的方式。

创建词法环境

词法环境有两个组成部分

环境记录是存储变量和函数声明的实际位置。
对外部环境的引用意味着它可以访问其外部词法环境。

词法环境有两种类型

全局环境是一个没有外部环境的词法环境,外部环境应用为null。拥有一个全局对象以及该对象拥有的对象和属性,还有用户自定义的全局变量。
函数环境,包括用户在函数定义的变量存储在环境记录中,包括argumnets对象。外部环境可能是全局环境,也可能是包含内部函数的外部函数环境。

GlobalExectionContext = {  // 全局执行上下文
  LexicalEnvironment: {       // 词法环境
    EnvironmentRecord: {        // 环境记录
      Type: "Object",              // 全局环境
      // 标识符绑定在这里 
      outer: <null>                // 对外部环境的引用
  }  
}

FunctionExectionContext = { // 函数执行上下文
  LexicalEnvironment: {       // 词法环境
    EnvironmentRecord: {        // 环境记录
      Type: "Declarative",         // 函数环境
      // 标识符绑定在这里             // 对外部环境的引用
      outer: <Global or outer function environment reference>  
  }  
}

创建变量环境

变量环境也是一个词法环境,因此它具有上面定义的词法环境的所有属性。

在 ES6 中,词法环境和变量环境的区别在于前者用于存储函数声明和变量( let 和 const )绑定,而后者仅用于存储变量( var )绑定。
变量提升的原因
在创建阶段,函数声明存储在环境中,而变量会被设置为 undefined(在 var 的情况下)或保持未初始化(在 let 和 const 的情况下)

执行阶段

进入执行上下文

添加形参,变量声明,函数声明,
同一作用域下,函数提升比变量提升得更靠前.

代码执行

修改变量对象的值

内存回收和内存泄露

标记清除(常用)
标记清除算法将“不再使用的对象”定义为“无法到达的对象”。即从根部(在JS中就是全局对象)出发定时扫描内存中的对象,凡是能从根部到达的对象,保留。那些从根部出发无法触及到的对象被标记为不再使用,稍后进行回收。
ES6 新出的两种数据结构:WeakSet 和 WeakMap,表示这是弱引用,它们对于值的引用都是不计入垃圾回收机制的。

常见的内存泄露

内存机制

基本类型:--> 栈内存(不包含闭包中的变量)
引用类型:--> 堆内存

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容