js引擎的执行过程

执行上下文和执行栈属于js引擎的执行过程的预编译阶段。

执行上下文(Execution Context)

执行上下文是当前 JavaScript 代码被解析和执行时所在环境的抽象概念。可以理解为当执行代码时做的准备工作。

执行上下文按照运行环境被分成三类:

  • 全局执行上下文(JS代码加载完毕后,进入代码预编译即进入全局环境)

  • 函数环境执行上下文(函数调用执行时,进入该函数环境,不同的函数则函数环境不同)

  • eval执行上下文(不建议使用,会有安全,性能等问题)

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

  • 变量对象(Variable object,VO),存储了在上下文中定义的变量和函数声明。在全局执行上下文中指window,函数执行上下文中就是活动对象(AO)
  • 作用域链(Scope chain),和原型链类似,当查找变量时,会先在当前上下文变量对象中查找,如果没有会去父级上下文变量对象中查找,直到全局上下文。这样由多个执行上下文的变量对象构成的链表就叫做作用域链
  • this

VO:变量对象(Variable object);

AO:活动对象(activation object),当进入函数执行上下文时,这个函数执行上下文的变量对象才会被激活,所以才叫 activation object,而只有被激活的变量对象,也就是活动对象上的各种属性才能被访问(进入函数上下文时创建活动对象)。

执行栈

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

首次运行JS代码时,会创建一个全局执行上下文并Push到当前的执行栈中。每当发生函数调用,引擎都会为该函数创建一个新的函数执行上下文并Push到当前执行栈的栈顶。

根据执行栈LIFO规则,当栈顶函数运行完成后,其对应的函数执行上下文将会从执行栈中Pop出,上下文控制权将移到当前执行栈的下一个执行上下文。

全局执行上下文在浏览器关闭或者标签关闭时才会出栈。

 var a = 'Hello World!';

 function first() {
console.log('Inside first function');
second();
console.log('Again inside first function');
} function second() {
console.log('Inside second function');
} first();
console.log('Inside Global Execution Context'); // Inside first function
// Inside second function
// Again inside first function
// Inside Global Execution Context

创建过程

创建阶段就是确定三个重要上下文属性的过程。

创建变量对象

  1. 创建arguments对象,检查当前上下文中的参数,建立该对象的属性与属性值,仅在函数环境(非箭头函数)中进行,全局环境没有此过程

  2. 检查当前上下文的函数声明,按代码顺序查找,将找到的函数提前声明,如果当前上下文的变量对象没有该函数名属性,则在该变量对象以函数名建立一个属性,属性值则为指向该函数所在堆内存地址的引用,如果存在,则会被新的引用覆盖。

  3. 检查当前上下文的变量声明,按代码顺序查找,将找到的变量提前声明,如果当前上下文的变量对象没有该变量名属性,则在该变量对象以变量名建立一个属性,属性值为undefined;如果存在,则忽略该变量声明

变量提升的原因:

在创建阶段,函数声明存储在环境中,而变量会被设置为 undefined(在 var 的情况下)或保持未初始化(在 let 和 const 的情况下)。所以这就是为什么可以在声明之前访问 var 定义的变量(尽管是 undefined ),但如果在声明之前访问 let 和 const 定义的变量就会提示引用错误的原因。这就是所谓的变量提升。

从创建顺序看,函数提升优先于变量提升。

创建作用域链

由多个执行上下文的变量对象构成的链表就叫做作用域链。

当函数创建的时候,函数有一个内部属性会保存所有父变量对象到其中。

进入函数上下文,创建 VO/AO 后,就会将活动对象添加到作用链的前端。

所以:

  • 作用域链的第一项永远是当前作用域(当前上下文的变量对象或活动对象);

  • 最后一项永远是全局作用域(全局执行上下文的活动对象);

  • 作用域链保证了变量和函数的有序访问,查找方式是沿着作用域链从左至右查找变量或函数,找到则会停止查找,找不到则一直查找到全局作用域,再找不到则会抛出引用错误。

确定This指向

全局执行上下文中变量对象的this属性指向为window,函数上下文则较为复杂,以后会详细介绍。

执行阶段

完成对所有变量的分配,最后执行代码。

总览

参考文档:

      理解JavaScript 中的执行上下文和执行栈

      JavaScript深入之执行上下文栈

      JavaScript深入之变量对象

      JavaScript深入之作用域链

      js引擎的执行过程(一)

JavaScript进阶之执行上下文和执行栈的更多相关文章

  1. 【进阶1-1期】理解JavaScript 中的执行上下文和执行栈(转)

    这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://mp.weixin.qq.com/s/tNl5B4uGdMkJ2bNdbbo82g 阅读笔记 执行上下文是当前 JavaScrip ...

  2. JavaScript 中的执行上下文和执行栈

    JavaScript - 原理系列 ​ 在日常开发中,每当我们接手一个现有项目后,我们总喜欢先去看看别人写的代码.每当我们看到别人写出很酷的代码的时候,我们总会感慨!写出这么优美而又简洁的代码的兄弟到 ...

  3. 深入理解 JavaScript 执行上下文和执行栈

    前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制.执行上下文和执行栈是 JavaScript ...

  4. 理解 Javascript 执行上下文和执行栈

    如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制.理解执行上下文和执行栈同样有助于理解其他的 Jav ...

  5. 转:JS高级学习笔记(8)- JavaScript执行上下文和执行栈

    必看参考: 请移步:博客园 JavaScript的执行上下文 深入理解JavaScript执行上下文和执行栈 JavaScript 深入之执行上下文 写在开头 入坑前端已经 13 个月了,不能再称自己 ...

  6. Javascript执行上下文和执行栈

    什么是执行上下文? 执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,JavaScript中运行任何的代码都是在执行上下文. 什么是执行栈? 执行栈,在其他编程语言中也被叫做 ...

  7. js执行上下文和执行栈

    执行上下文就是JavaScript 在被解析和运行时环境的抽象概念,JavaScript 运行任何代码都是在执行上下文环境中运行的,执行上下文包括三个周期:创建——运行——销毁,重点说一下创建环节. ...

  8. 关于javascript中的 执行上下文和对象变量

    什么是执行上下文 当浏览器的解释器开始执行我们的js代码的时候,js代码运行所处的环境可以被认为是代码的执行上下文,执行上下文(简称-EC)是ECMA-262标准里的一个抽象概念,用于同可执行代码(e ...

  9. JavaScript 中的执行上下文和调用栈是什么?

    http://zcfy.cc/article/what-is-the-execution-context-amp-stack-in-javascript-by-david-shariff-4007.h ...

随机推荐

  1. [MST] Restore the Model Tree State using Hot Module Reloading when Model Definitions Change

    n this lesson, we will set up Hot Module Reloading(HMR), making it possible to load new definitions ...

  2. Codeforces Round #256 (Div. 2) B. Suffix Structures(模拟)

    题目链接:http://codeforces.com/contest/448/problem/B --------------------------------------------------- ...

  3. 【甘道夫】Sqoop1.99.3基础操作--导入Oracle的数据到HDFS

    第一步:进入clientShell fulong@FBI008:~$ sqoop.sh client Sqoop home directory: /home/fulong/Sqoop/sqoop-1. ...

  4. 在Linux的终端中显示BMPString的内容

    在上一篇博文中,介绍了怎样在 Windows 的控制台界面下输出 BMPString 的内容,可是那里的方法在 Linux 下不适用.假设将那里的演示样例代码放到 Linux 下运行.输出的结果为乱码 ...

  5. linux程序设计——个人总结

    linux程序设计--个人总结 到今天为止,<linux程序设计>学习基本完毕了.从五月下旬開始接触linux,学习安装Ubuntu14.04,六月份開始学习<linux程序设计&g ...

  6. POJ 2528 Mayor&#39;s posters 离散化和线段树题解

    本题就是要往墙上贴海报,问最后有多少可见的海报. 事实上本题的难点并非线段树,而是离散化. 由于数据非常大,直接按原始数据计算那么就会爆内存和时间的. 故此须要把数据离散化. 比方有海报1 6   7 ...

  7. HDU1232 畅通project 并查集

    这道题跟HDU 1213 How Many Tables 并查集很接近,都是赤裸裸的并查集的题. 思路:如果还须要建n-1条路.每并一次就自减1. 參考代码: #include<stdio.h& ...

  8. 使用React Hook后的一些体会

    一.前言 距离React Hook发布已经有一段时间了,笔者在之前也一直在等待机会来尝试一下Hook,这个尝试不是像文档中介绍的可以先在已有项目中的小组件和新组件上尝试,而是尝试用Hook的方式构建整 ...

  9. [GDKOI2010] 圈地计划(网络流)

    题2链接:https://www.luogu.org/problemnew/show/P1935 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots ...

  10. spring boot 的常用注解使用 总结

    附:Spring Boot 官方文档学习(一)入门及使用见https://www.cnblogs.com/larryzeal/p/5799195.html @RestController和@Reque ...