美文网首页
执行上下文(个人笔记)

执行上下文(个人笔记)

作者: kevision | 来源:发表于2020-07-25 13:17 被阅读0次

本文参考:javaScript执行上下文和执行上下文栈
一篇文章看懂JS执行上下文
什么是执行上下文?什么是调用栈?

一:什么是执行上下文?

JS代码在执行前,JS引擎总要做一番准备工作,这份工作其实就是创建对应的执行上下文;

执行上下文有且只有三类,全局执行上下文,函数上下文,与eval上下文;由于eval一般不会使用,这里不做讨论。

当JavaScript代码运行的时候,确定它运行所在的环境是非常重要的。运行环境由下面三种不同的代码类型确定:
全局代码(Global Code):代码首次执行时候的默认环境
函数代码(Function Code):每当执行流程进入到一个函数体内部的时候
Eval代码(Eval Code):当eval函数内部的文本执行的时候

您可以在网上找到大量关于scope的参考资料。
1.全局执行上下文

全局执行上下文只有一个,在客户端中一般由浏览器创建,也就是我们熟知的window对象,我们能通过this直接访问到它。

image

全局对象window上预定义了大量的方法和属性,我们在全局环境的任意处都能直接访问这些属性方法,同时window对象还是var声明的全局变量的载体。我们通过var创建的全局对象,都可以通过window直接访问。

image image
2.函数执行上下文

函数执行上下文可存在无数个,每当一个函数被调用时都会创建一个函数上下文;需要注意的是,同一个函数被多次调用,都会创建一个新的上下文。

说到这你是否会想,上下文种类不同,而且创建的数量还这么多,它们之间的关系是怎么样的,又是谁来管理这些上下文呢,这就不得不说说执行上下文栈了。

注意!全局上下文有且只有一个,程序中其他任意的上下文都可以访问全局上下文。你可以拥有任意数量的函数上下文。每一次函数调用都会创建一个新的上下文,它会创建一个私有域,函数内部做出的所有声明都会放在这个私有域中,并且这些声明在当前函数作用域外无法直接访问。一个函数可以访问它所在的上下文外部的变量,但是一个外部的上下文无法访问内部函数内部声明的变量/函数。为什么会发生这样的情况?代码究竟是如何被解析的呢?

二:执行上下文栈

执行上下文栈(下文简称执行栈)也叫调用栈,执行栈用于存储代码执行期间创建的所有上下文,具有LIFO(Last In First Out后进先出,也就是先进后出)的特性。
JS代码首次运行,都会先创建一个全局执行上下文并压入到执行栈中,之后每当有函数被调用,都会创建一个新的函数执行上下文并压入栈内;由于执行栈LIFO的特性,所以可以理解为,JS代码执行完毕前在执行栈底部永远有个全局执行上下文。

浏览器中的JS解释器是单线程的。也就是说在浏览器中同一时间只能做一个事情,其他的action和event都会被排队放入到执行栈中(Execution Stack)。下图表示了一个单线程栈的抽象视图

image

如我们所知,当一个浏览器第一次load你的代码的时候,首先它会进入到一个全局执行上下文中。如果在你的全局代码中,你调用了一个函数,那么程序的执行流程会进入到被调用的函数中,并创建一个新的执行上下文,并将这个上下文推入到执行栈顶。
如果在当前的函数中,你又调用了一个函数,那么也会执行同样的操作。执行流程计入到刚被调用的函数内部,重新创建一个新的执行上下文,并再次推入到执行栈顶。浏览器会一直执行当前栈顶的执行上下文,一旦函数执行完毕,该上下文就会被推出执行栈。下面的例子展示了一个递归函数以及该程序的执行栈:

(function foo(i) {
  if (i === 3) {
    return;
  }
  else {
    foo(++i);
  }
}(0));

image

这个代码循环调用了三次,每次对i累加1。每次函数foo调用的时候,都会有一个创建新的执行上下文。一旦上下文完成了执行,就会推出栈,将控制流返回给它下面的执行上下文,这样一直到全局上下文。

例2:

function f1() {
    f2();
    console.log(1);
};

function f2() {
    f3();
    console.log(2);
};

function f3() {
    console.log(3);
};

f1();//3 2 1

我们通过执行栈与上下文的关系来解释上述代码的执行过程,为了方便理解,我们假象执行栈是一个数组,在代码执行初期一定会创建全局执行上下文并压入栈,因此过程大致如下:

//代码执行前创建全局执行上下文
ECStack = [globalContext];
// f1调用
ECStack.push('f1 functionContext');
// f1又调用了f2,f2执行完毕之前无法console 1
ECStack.push('f2 functionContext');
// f2又调用了f3,f3执行完毕之前无法console 2
ECStack.push('f3 functionContext');
// f3执行完毕,输出3并出栈
ECStack.pop();
// f2执行完毕,输出2并出栈
ECStack.pop();
// f1执行完毕,输出1并出栈
ECStack.pop();
// 此时执行栈中只剩下一个全局执行上下文

关于执行栈,有5点需要记住:

  • 单线程
  • 同步执行
  • 一个全局上下文
  • 无数的函数上下文
  • 每次函数调用都会创建一个新的执行上下文,即使是调用自身

三:执行上下文详解

我们已经知道每当一个函数调用发生,都会创建一个新的执行上下文。但是在JS解释器内部,每次调用一个执行上下文都分为两个步骤

  1. 创建阶段[在函数被调用,但还未执行任何代码之前]
  1. 激活/代码执行阶段
  • 分配变量,以及到函数的引用,然后解析/执行代码

一个执行上下文从概念上可以视为一个包含三个property的Object

链接:https://www.jianshu.com/p/12fab84daeba

相关文章

  • 执行上下文(个人笔记)

    本文参考:javaScript执行上下文和执行上下文栈一篇文章看懂JS执行上下文什么是执行上下文?什么是调用栈? ...

  • 编写高效的javascript

    读书笔记 1.当执行javascript代码时,javascript引擎会创建一个执行上下文。执行上下文设定了代码...

  • 再学 this

    执行上下文主要分为三种:全局执行上下文、函数执行上下文、eval执行上下文。而this和执行上下文是相互绑定的,所...

  • 对js执行上下文的理解

    执行上下文 执行上下文有三种: 全局执行上下文在执行全局代码的时候会创建全局上下文 函数执行上下文在执行函数代码的...

  • 深入浅出执行上下文、词法环境、变量环境

    执行上下文的概念 执行上下文:javascript 代码解析和执行时所在的环境。 执行上下文的类型 执行上下文分为...

  • js深度剖析 : 执行环境和作用域链

    执行上下文 execution context 又称执行上下文或者执行环境. 执行上下文是JavaScript中一...

  • js 代码的执行

    执行上下文 EC(Execution Context):代码自己执行所在的环境 全局执行上下文 函数执行上下文 ...

  • 2019-01-07变量和函数预解析,数组,定时器弹框,当天作业

    变量和函数预解析处理执行上下文代码分为两个阶段:进入执行上下文执行代码进入执行上下文:进入执行上下文,方法的变量对...

  • JavaScript执行上下文和执行栈

    执行上下文(Execution Context) 什么是执行上下文 简而言之,执行上下文就是当前JavaScrip...

  • JS 执行上下文

    理解执行上下文 执行上下文(Execution Context): 函数执行前进行的准备工作(也称执行上下文环境)...

网友评论

      本文标题:执行上下文(个人笔记)

      本文链接:https://www.haomeiwen.com/subject/lfgmhktx.html