【JavaScript由浅入深】执行上下文

【JavaScript由浅入深】执行上下文

在了解这些之前我们先来看看JavaScript语言的执行过程,大致分为下面几个步骤:

  1. 语法检查:对整体代码进行词法分析,语法分析
  2. 代码预解析:生成GO、AO对象(也称作预编译)
  3. 解释执行:逐行运行代码

一、执行上下文

1.1 执行上下文类型

(1)全局执行上下文

任何不在函数内部的都是全局执行上下文,它首先会创建一个全局的window对象,并且设置this的值等于这个全局对象,一个程序中只有一个全局执行上下文。

(2)函数执行上下文

当一个函数被调用时,就会为该函数创建一个新的执行上下文,函数的上下文可以有任意多个。

(3)eval函数执行上下文

执行在eval函数中的代码会有属于他自己的执行上下文,不过eval函数不常使用。

1.2 执行上下文栈

  • js引擎内部有一个执行上下文栈(Execution Context Stack,简称ECS),它是用于执行代码的调用栈
  • 当JavaScript执行代码时,首先遇到全局代码,会创建一个全局执行上下文并且压入执行栈中
  • 每当遇到一个函数调用,就会为该函数创建一个新的执行上下文并压入栈顶
  • 引擎会执行位于执行上下文栈顶的函数
  • 当函数执行完成之后,执行上下文从栈中弹出,继续执行下一个上下文
  • 当所有的代码都执行完毕之后,从栈中弹出全局执行上下文

1.3 VO对象

每一个执行上下文关联一个VO(Variable Object,变量对象),变量和函数声明会被添加到这个VO对象中

简单来说执行上下文就是指:

在执行一点JS代码之前,需要先解析代码。解析的时候会先创建一个全局执行上下文环境,先把代码中即将执行的变量、函数声明都拿出来,变量先赋值为undefined函数先声明好可使用。这一步执行完了,才开始正式的执行程序。

在一个函数执行之前,也会创建一个函数执行上下文环境,跟全局执行上下文类似,不过函数执行上下文会多出this、arguments和函数的参数。

  • 全局上下文:变量定义,函数声明
  • 函数上下文:变量定义,函数声明,thisarguments

二、AO与GO

  • AO和 GO,说白了就是局部变量对象和全局变量对象。
    • AO(Activation Object ):其包含了函数执行期的上下文内容。
    • GO(Clobal Object)):其包含全局执行的上下文内容。
  • AO是一个即时的存储容器,函数执行完毕以后,AO是要销毁的。

三、全局代码执行过程

  • js引擎会在执行代码之前,会在堆内存中创建一个全局对象:Global Object(GO)

    • 该对象 所有的作用域(scope)都可以访问;
    • 里面会包含Date、Array、String、Number、setTimeout、setInterval等等;
    • 其中还有一个window属性指向自己;
  • 执行上下文栈执行全局的代码块

    • 全局的代码块为了执行会构建一个全局执行上下文 Global Execution Context(GEC);
    • GEC会 被放入到执行上下文栈(ECS)中 执行;
  • GEC被放入到ECS中里面包含两部分内容:

    • 第一部分:在代码执行前,在parser转成AST的过程中,会将全局定义的变量、函数等加入到GlobalObject中,但是并不会 赋值;
    • 这个过程也称之为变量的作用域提升(hoisting)
    • 第二部分:在代码执行中,对变量赋值,或者执行其他的函数
  • 当全局代码被执行的时候,VO就是GO对象

以下代码的全局代码执行过程如下:

var message = "Global Message"
function fn() {
    var message = "foo Message"
    }

var num1 = 10
var num2 = 20
var result = num1 + num2

foo()

执行前:

在这里插入图片描述

执行后:

在这里插入图片描述

四、函数执行代码过程

  • 在执行的过程中执行到一个函数时,就会根据函数体创建一个函数执行上下文(Functional Execution Context,简称FEC), 并且压入到执行上下文栈中。
  • 因为每个执行上下文都会关联一个VO,那么函数执行上下文关联的VO是什么呢?
    • 当进入一个函数执行上下文时,会创建一个AO对象(Activation Object)
    • 这个AO对象会使用arguments作为初始化,并且初始值是传入的参数
    • 这个AO对象会作为执行上下文的VO来存放变量的初始化;

以下代码的函数代码执行过程如下:

var message = "Global Message"

function fn(num) {
    var message = "foo Message"
    var age = 18
    var height = 1.88
    console.log("foo function");
}


foo(123) 

var num1 = 10
var num2 = 20
var result = num1 + num2

执行前:

在这里插入图片描述

执行后:

在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端程序员小张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值