细说JS系列(六)

138 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

铃铛说点题外话

这一篇的前提我打算对上一篇的知识进行一个总结,有私聊我的说写的有点细碎,那我先对上一篇的V8引擎座做一个总结。

  1. parse模块会将JS代码转换AST抽象语法树,这是因为解释器并不能直接认识JS代码:如果函数没有被调用,那么是不会被转换成AST抽象语法树的
  2. Ignition是一个解释器,会将AST转换成字节码。
    • 同时会收集TurboFan优化所需要的信息
    • 如果函数只调用一次,Ignition会执行解释执行字节码
  3. TurboFan是一个编译器,可以将字节码编译为CPU可以直接执行的机器码
    • 如果一个函数被多次调用,那么就会被标记为热点函数,那么就会经过TurboFan转换成优化的机器码,提供diamagnetic的执行性能

    • 但是,机器码实际上也会被还原为字节码,这是因为如果后续执行函数的过程中,类型发生了变化(比如一个sum函数原来执行的是number类型,后来变成了string类型),之前优化的机器码并不能正确的处理运算,就会你想的转换成字节码。

关于浏览器的内容目前就先说到这里,今天这一篇我们来说说提升的事情。

铃铛说正文

console.log(age)
var age = 18

我们先看看上面这段代码会输出什么?答案是它并不会报错会输出一个undefined 为什么会造成这样的结果呢,这就涉及到一个变量提升的事情。

这里面就会用到我们之前学习过的V8引擎,这个输出结果和我们V8引擎解析有关

  • 在编译的时候,V8 引擎( js 引擎)会创建一个 globalObject 全局对象,这里面包含了我们平时用到的 StringDatesetTimeout ,等等这些类。window 也指向这个的全局对象。
  • 在创建的时候是可以确定我们哪些变量是定义过的,将这些变量添加到全局对象 globalObject 中,但是这个时候,值还没有确定。
  • 所以上述代码输出的结果是 undefined.

V8引擎会将上面的那段代码解析为如下

var globalObject = {
    String"类",
    Date"类",
    setTimeout"函数",
    window: globalObject,
    nameundefined
}

跟铃铛说再见

这一篇我们用相当大的篇幅对V8引擎的解析进行一个总结,也引出了一个新的知识点:变量提升,既然变量有提升,那么函数有提升吗?大家可以思考一下