乐趣区

深入理解JavaScript-执行上下文

只有了解了执行上下文,能力更好地了解 JavaScript 语言自身,比方变量晋升,作用域,闭包等

执行上下文

执行上下文是以后代码的执行环境。

执行上下文次要是三种类型:

  1. 全局执行上下文:全局执行环境是最外围的一个执行环境,在浏览器的全局对象是 window, this 指向这个对象
  2. 函数执行上下文:能够有无数个,函数被调用的时候会被创立。每次调用函数都会创立一个新的执行上下文。
  3. eval 执行上下文,很少用。

每个执行上下文,都有三个重要属性:

  1. 变量对象 (variable object, VO): 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保留在这个对象中。尽管咱们编写的代码无法访问这个对象,但解析器在解决数据时会在后盾应用它。

在函数上下文中,应用流动对象 (activation object, AO) 来示意变量对象。流动对象和变量对象其实是一个货色,只有当进入一个执行环境时,这个执行上下文的变量对象才会被激活,此时称为 流动对象(AO),只有流动对象上的属性能力被拜访。

  1. 作用域链(scope chain):当代码在一个环境中执行时,会创立变量对象的一个作用域链。作用域链的用处,是保障对执行环境有权拜访的所有变量和函数的有序拜访。
  2. this

执行上下文的生命周期:创立 -> 执行 -> 回收

1. 创立阶段:

1.1 创立变量对象:
  • 初始化函数的参数 arguments
  • 函数申明
  • 变量申明

举个简略的例子来了解变量对象

function getName(name) {
    var b = 2;
    function foo() {};
    var bar = function() {};

}
getName('lucystar')

此时的 AO 大抵如下

AO = {
    arguments: {
        0: 'lucystar',
        length: 1
    },
    name: 'lucystar',
    b: undefined,
    foo: reference to function foo(){},
    bar: undefined
}

下面例子中波及到了变量晋升和函数晋升,之前在 从 JS 底层了解 var、let、const 这边文章中也介绍过

1.2 创立作用域链

函数的作用域在函数定义的时候就确定了。作用域链自身蕴含变量对象,当查找变量时,会先从以后上下文中的变量对象中查找,如果没有找到,就会从父级执行上下文的变量对象中查找,始终找到全局执行上下文的变量对象

1.3 确定 this 的指向

这部分又分为多种状况,具体的能够查看另一篇文章 一文了解 this&call&apply&bind

2. 执行阶段

执行变量赋值,代码执行

3. 回收阶段

执行上下文出栈被垃圾回收机制进行回收。对于内存回收的内容,能够查看 V8 内存治理及垃圾回收机制

执行上下文栈

执行上下文栈是用来治理执行上下文的。在执行上下文创立好后,JavaScript 引擎会将执行上下文压入到栈中,通常把这种用来治理执行上下文的栈称为执行上下文栈,又称调用栈。

let a = 'javascript';

function foo() {console.log('foo');
    bar();}
function bar() {console.log('bar');
}
foo();

  1. 上述代码在浏览器加载时,JavaScript 引擎创立了一个全局执行上下文并把它压入到以后执行栈。
  2. 当遇到 foo() 函数调用时,JavaScript 引擎创立了一个 foo 函数执行上下文并把它压入到以后执行栈的顶部。
  3. 当从 foo() 函数外部调用 bar() 函数时,JavaScript 引擎创立了一个 bar 函数执行上下文并把它压入到以后执行栈的顶部。
  4. 当函数 bar 执行结束,它的执行上下文会从以后栈中弹出,管制流程达到下一个执行上下文,即 foo() 函数的执行上下文。
  5. 当 foo() 执行实现,它的执行上下文从栈弹出,管制流程达到全局执行上下文,一旦所有代码执行实现,javaScript 引擎就从以后栈中移除全局执行上下文。

为什么根本数据类型存储在栈中,援用数据类型存储在堆中?JavaScript 引擎须要用栈来维护程序执行期间的上下文的状态,如果栈空间大了的话,所有数据都寄存在栈空间外面,会影响到上下文切换的效率,进而影响整个程序的执行效率。

参考

  • JavaScript 深刻之执行上下文栈
  • JavaScript 深刻之执行上下文
  • JavaScript 深刻之变量对象
  • 深刻了解 JavaScript 系列(11):执行上下文(Execution Contexts)
  • 《JavaScript 高级程序设计(第三版)》
退出移动版