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

2018-12-17  本文已影响0人  虎妞先生

什么是执行上下文?

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,表示这是弱引用,它们对于值的引用都是不计入垃圾回收机制的。

常见的内存泄露

内存机制

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

上一篇下一篇

猜你喜欢

热点阅读