白话JS引擎运行过程

JS引擎对代码解析执行的过程,有两个阶段。
第一个阶段是构建语法树
第二个阶段是对语法树进行解析执行

第一阶段:构建语法树

构建过程按下不表,日后填坑。
若语法树无法构造,报语法错误。

第二阶段:解析执行

解析执行有三阶段:创建,执行,执行完毕。

白话JS引擎运行过程_第1张图片
解析执行三个阶段

创建阶段

创建阶段,创建什么?
创建执行上下文(Execution context)

白话JS引擎运行过程_第2张图片
执行上下文

创建执行上下文这个过程,也叫预解析(preparse).
预解析(preparse)的内容如下:

1. 创建变量对象(Variable Object)
2. 建立作用域链(Scope chain)
3. 确定this引用

1. 创建变量对象(Variable Object)

变量对象是一个对象。
变量对象的属性有函数形参(arguments)变量声明(variables)函数声明(functions)

创建变量对象的过程

示例代码1:

 function fn(a){
    console.log(a);
    var a = 123;
    console.log(a);
    
    function a(){};
    console.log(a);
    
    var b = function(){};
    console.log(b);
    
    function d(){};
 }
 
 //调用函数
 fn(1);

执行fn(1)时,对fn预解析的创建变量对象过程如下:

  1. 创建一个空对象
vo:{
// 空对象
}
  1. 形参变实参
// 找形参
vo:{
  a : undefined,
}
// 形参变实参
vo:{
  a : 1,
}
  1. 找变量声明
vo:{
  a : undefined,
  b : undefined
}
  1. 找函数声明
vo:{
    a : function a(){},
    b : undefined,
    d : function d(){}
}

2. 建立作用域链(Scope chain)

作用域链是什么?是一个数组。
数组内容是父变量对象
创建阶段作用域链就这么点内容。
举个例子:

function foo() {
    function bar() {
    }
}

foo();

创建阶段时,foo的作用域链为

foo.[[scope]] = [
  globalContext.VO
];

属性[[scope]]即foo函数的作用域链。globalContext.VO是指全局上下文的变量对象

执行foo函数。也就是bar函数创建阶段,bar的作用域链为

bar.[[scope]] = [
    fooContext.AO,
    globalContext.VO
];

而此时foo的作用域链为

foo.[[scope]] = [
  [AO],
  globalContext.VO
];

这里的[AO]是指foo函数的活动对象(Active Object)。本质就是foo函数的变量对象(Variable Object)。
同一个东西不同阶段的称呼而已。

闭包

每个函数都有作用域链,引用了父活动对象或全局变量对象。
所以,每个函数都是闭包。
因为,闭包的定义是引用了自由变量的函数。

3. 确定this指向

创建阶段的this指向undefined

执行阶段

1.修改活动对象。
2.遇到异步代码,涉及到macro-task(宏任务)micro-task(微任务)
3.赋值操作,进行内存分配。

this的变化

谁调用函数,该函数的执行上下文的this指向谁。
函数调用场景:

  • new调用
  • 对象调用
  • 系统调用

JavaScript中this的运行机制及爬坑指南

执行完毕阶段

垃圾回收策略有两个,标记清除,引用计数(已淘汰)。
标记清除策略:
(1)创建阶段对当前执行上下文的变量进行标记。
(2)执行阶段,执行到所需变量的操作时,去掉它的标记。
(3)执行完毕阶段,有标记的变量就被视为准备删除的变量。
(4)垃圾收集器销毁带标记的变量,回收它们所占用的内存空间。

引用计数被淘汰的原因是循环引用会导致垃圾回收失败。
垃圾回收策略对写代码的参考:

参考:
Google V8 的垃圾回收引擎
聊聊V8引擎的垃圾回收

参考:
https://my.oschina.net/ffwcn/blog/209465
https://juejin.im/post/5aa6693df265da23884cb571
https://www.cnblogs.com/ivehd/p/executionContext.html

你可能感兴趣的:(白话JS引擎运行过程)