JS高级——函数执行、作用域链内存结构图

一、JavaScript的执行过程

假如我们有下面一段代码,它在JavaScript中是如何被执行的呢?

1.1 第一步:初始化全局对象

  • js引擎会在执行代码之前,会在堆内存中创建一个全局对象:Global Object(GO)
  • 该对象 所有的作用域(scope)都可以访问;
  • 里面会包含Date、Array、String、Number、setTimeout、setInterval等等;
  • 其中还有一个window属性指向自己;
    在这里插入图片描述

1.2 执行上下文栈(调用栈)

js引擎内部有一个执行上下文栈(Execution Context Stack,简称ECS),它是用于执行代码的调用栈。

那么现在它要执行谁呢?执行的是全局的代码块:

  • 全局的代码块为了执行会构建一个 Global Execution Context(全局执行上下文)(GEC);
  • GEC(全局执行上下文)会 被放入到ECS(执行上下文栈)中 执行;

GEC被放入到ECS中里面包含两部分内容:

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

1.3 第二步:将全局执行上下文放入执行上下文栈中

在这里插入图片描述

1.4 第三步:全局执行上下文开始执行代码

在这里插入图片描述
在这里插入图片描述

二、遇到函数如何执行?

在执行的过程中执行到一个函数时,就会根据函数体创建一个函数执行上下文(Functional Execution
Context,简称FEC),并且压入到EC Stack中。

FEC中包含三部分内容:

  • 第一部分:在解析函数成为AST树结构时,会创建一个Activation Object(AO):
    AO中包含形参、arguments、函数定义和指向函数对象、定义的变量;
  • 第二部分:作用域链:由VO(在函数中就是AO对象)和父级VO组成,查找时会一层层查找;
  • 第三部分:this绑定的值
    在这里插入图片描述

下面看看如下代码的执行过程:
在这里插入图片描述

2.1 第一步:初始化全局对象

在这里插入图片描述

2.2 第二步: 将全局执行上下文 放入 执行上下文栈中

在这里插入图片描述

2.3 第三步:全局执行上下文 开始执行代码

在这里插入图片描述

3.4 第四步:遇到函数调用则 创建函数执行上下文FEC,并把FEC放入 执行上下文栈ECS中

在这里插入图片描述

3.5 第五步:函数执行上下文FEC开始执行代码

在这里插入图片描述

最后浏览器控制台输出: foo

三、练习题:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:函数中的变量没有使用var关键字来定义时,相当于会在GO对象中定义并保存这个变量,所以即使函数执行完成后,函数内的变量会被销毁,但是函数外部仍然可以获取到这个变量

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值