Loading

调用堆栈(一)-执行上下文和执行栈

执行上下文概念及类型

执行上下文可以理解为javascript代码被执行时的环境。

在js中,执行上下文分为以下三种类型:

  • 全局执行上下文:只有一个,浏览器中的全局对象就是window对象,this指向这个全局对象。
  • 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文。
  • Eval函数执行上下文:指的是运行在eval函数中的代码,很少用而且不建议使用。

执行栈概念

执行栈,也叫调用栈,具有LIFO(后进先出)的结构,用于存储代码执行期间创建的所有执行上下文。

根据执行上下文的类型可以知道,在js程序执行过程中,一定会出现多种不同的执行上下文,但是,js是单线程语言,不能同时做多件事情。当js解释器初始执行代码时,它会首先默认进入全局上下文,而且每次调用一个函数都将会创建一个新的执行上下文,每次新创建的执行上下文都会被添加到作用域链的顶部,也就是执行栈或者调用栈。浏览器总是运行于调用栈的顶部的当前执行上下文。一旦完成,当前执行上下文就会从栈顶移除。
可以看下面的一个例子:

  var a = 1; // 1、全局上下文环境
  function bar (x) {
        console.log('bar')
        var b = 2;
        fn(x + b); // 3、fn上下文环境
  }
  function fn(c) {
        console.log(c)
  }
  bar(3); // 2、bar上下文环境

如下图:

执行上下文的创建

我们现在已经知道,每当调用一个函数时,一个新的执行上下文就会被创建出来。然而,在JavaScript引擎内部,这个执行上下文的创建过程具体分为两个阶段 :1、创建阶段2、执行阶段

创建阶段(发生在当调用一个函数时,但是在执行函数体内的具体代码以前)
---建立变量,函数,arguments对象,参数
---建立作用链
---确定this的值
代码执行阶段:
---变量赋值,函数引用,执行其他代码

创建阶段

建立variableObject对象;
建立arguments对象,检查当前上下文中的参数,建立该对象下的属性以及属性值。

检查当前上下文中的函数声明:每找到一个函数声明,就在variableObject下面用函数名建立一个属性,属性值就是指向该函数在内存中的地址的一个引用,如果上述函数名已经存在与variableObject下,那么对应的属性值就会被新的引用所覆盖。

检查当前上下文中的变量声明:每找到一个变量的声明,就在variableObject下,用变量名建立一个属性,属性值为undefined。如果该变量名已经存在于variableObject属性中,直接跳过(防止指向函数的属性的值被变量属性覆盖为undefined),原属性值不会被修改。

初始化作用域链;
确定上下文中this的指向对象。

执行阶段

执行函数体中的代码,一行一行地运行代码,给variableObject中的变量属性赋值。

看个例子:

  function f1(){
       var n = 999;
       function f2(){
           alert(n);
      }
      return f2;
  }
  var result = f1();
  result();//999

过程如下:

1、初始时全局上下文先入栈,遇到函数声明f1,用该函数名建立了一个属性指该函数f1,遇到变量声明result初始为undefined。
2、全局代码在执行过程中,遇到了f1()函数,执行var result=f1(),因此f1会创建对应的执行上下文并入栈。
3、在f1的可执行代码中,虽然声明了一个函数f2,但是并没有执行任何函数,因此也就不会产生别的执行上下文,代码执行结束后,f1自然会出栈
4、f1()函数执行后,开始执行result(),result函数会创建一个新的执行上下文,这个时候result的上下文入栈。
5、这个result()其实就是在f1中声明的函数f2,因此这个时候就会执行f2的代码,由于f2中没有产生新的执行上下文,因此执行完就会出栈。

参考:
https://muyiy.cn/blog/1/1.1.html#执行上下文的创建
https://github.com/LinDaiDai/niubility-coding-js/blob/master/JavaScript/调用堆栈/JavaScript进阶-执行上下文.md
https://m528964214.blog.csdn.net/article/details/87898267
https://www.cnblogs.com/mcray/p/7003245.html?utm_source=itdadao&utm_medium=referral

posted @ 2020-11-20 15:19  Yang-0394  阅读(549)  评论(0)    收藏  举报