【JS进阶】JavaScript运行原理


一.V8引擎执行原理

V8引擎本身的源码非常复杂,大概有超过100w行C++代码,通过了解它的架构,我们可以知道它是如何对JavaScript执行的:
在这里插入图片描述

  • Parse模块会将JavaScript代码转换成AST(抽象语法树),这是因为解释器并不直接认识JavaScript代码;

    • 如果函数没有被调用,那么是不会被转换成AST的;
  • Ignition是一个解释器,会将AST转换成ByteCode(字节码)

    • 同时会收集TurboFan优化所需要的信息(比如函数参数的类型信息,有了类型才能进行真实的运算);
    • 如果函数只调用一次,Ignition会解释执行ByteCode;
  • TurboFan是一个编译器,可以将字节码编译为CPU可以直接执行的机器码;

    • 如果一个函数被多次调用,那么就会被标记为热点函数,那么就会经过TurboFan转换成优化的机器码,提高代码的执行性能;
    • 但是,机器码实际上也会被还原为ByteCode,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执行的是number类型,后来执行变成了string类型),之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码;

二.JS执行上下文

1.执行上下文类型

(1)全局执行上下文

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

(2)函数执行上下文

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

(3)eval执行上下文

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

2.执行上下文栈

  • JavaScript引擎使用执行上下文栈来管理执行上下文
  • 当JavaScript执行代码时,首先遇到全局代码,会创建一个全局执行上下文并且压入执行栈中,每当遇到一个函数调用,就会为该函数创建一个新的执行上下文并压入栈顶,引擎会执行位于执行上下文栈顶的函数,当函数执行完成后,执行上下文从栈中弹出,继续执行下一个上下文。当所有代码都执行完毕后,从栈中弹出全局执行上下文。

三.执行过程

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

1.全局代码执行过程

在执行JS代码之前,需要先解析代码。解析的时候会先创建一个全局执行上下文环境,先把代码中即将执行的变量、函数声明拿出来被添加到VO(Variable Object)对象中,变量先赋值为undefined,函数声明好可使用。这一步完成了,才开始正式执行程序。当全局代码被执行的时候,VO就是GO对象了。
执行前:
在这里插入图片描述
执行后:
在这里插入图片描述

2.函数代码执行过程

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

执行前:
在这里插入图片描述
执行后:
在这里插入图片描述

四.作用域和作用域链

1、全局作用域和函数作用域

(1)全局作用域

  • 最外层函数和最外层函数外面定义的变量拥有全局作用域
  • 所有未定义直接赋值的变量自动声明为全局作用域
  • 所有window对象的属性拥有全局作用域

(2)函数作用域

  • 函数作用域声明在函数内部的变量,一般只有固定代码片段可以访问到
  • 作用域是分层的,内层作用域可以访问外层作用域,反之不行

2.块级作用域

  • 使用ES6新增的let和const指令可以声明块级作用域,块级作用域可以在函数中创建也可以在一个代码块中创建
  • let和const声明的变量不会有变量提升,也不可以重复声明
  • 在循环中比较适合绑定块级作用域,这样就可以把声明的计数器变量限制在循环内部

3.作用域链

在当前作用域中查找所需变量,但是该作用域没有这个变量,那这个变量就是自由变量。如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃炫迈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值