1

前端-JavaScript运行原理

 2 years ago
source link: https://segmentfault.com/a/1190000040851732
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

理解JavaScript运行原理,我们需要理解以下两方面内容。

  • JavaScript引擎。
  • JavaScript运行时环境。

JavaScript引擎

什么是JavaScript引擎

JavaScript引擎是一个计算机程序,它的主要作用是JavaScript运行时将源码编译为机器码。

每个主流Web浏览器都有自己的JavaScript引擎,它通常由web浏览器供应商开发。

  • Google Chrome V8。
  • Mozilla Firefox Spider Monkey。
  • Safari Javascript Core Webkit。
  • Edge (Internet Explorer)

以前的JavaScript引擎主要在web浏览器使用,不过随着nodejs的出现就打破了这种局限。

V8包含了解析器(parser),解释器(Ignition),优化编译器(TurboFan )。

解析器(parser):用于生成抽象语法树。

解释器(Ignition):将源码转换为字节码。

解释器

优化编译器(TurboFan ):进行一些优化编译优化处理,比如内联缓存。

下面是V8引擎的大体工作流程。

  1. 首先解析器先生成一个抽象语法树。
  2. 然后解释器根据语法树生成V8格式的字节码。
  3. 优化编译器再将字节码编译成机器码。

源码转化为机器码流程

运行时环境

浏览器运行环境中,浏览器提供了Web API,如:HTTP请求,计时器,事件等。

服务器运行环境中,nodejs提供了API。

下面是JavaScript在浏览器中运行时的架构,它包含一个内存堆、一个内存栈、一个事件循环、一个回调队列。

JavaScript运行时架构

  • 内存栈(stack),一个连续的内存区域,为每个执行的函数分配本地上下文。
  • 内存堆( heap), 一个更大的内存区域,存储动态分配的所有内容。
  • 调用栈(call stack), 一种数据结构,记录了我们在程序中的位置。
  • 回调队列(callback queue),存储异步任务的回调函数。
  • 事件循环(event loop),持续检查调用栈是否为空,如果为空,将回调队列中头部回调函数移动到调用栈执行。

运行时的调用栈

下面代码展示了JavaScript执行的调用栈变化。

JavaScript调用栈

function add(x, y) {
    return x + y;
}

function print(x, y) {
    console.log('x+y=',add(x, y))
}

print(1, 3)

JavaScript先执行了print函数,然后调用Web API setTimeout(),Web API存储了setTimeout() 的回调函数,3秒后将回调函数添加到回调队列,事件循环发现调用栈为空,于是将队列里的回调函数移至调用栈执行。

异步任务

function add(x, y) {
    return x + y;
}

function print(x, y) {
    setTimeout(function (){
        console.log('x+y=',add(x, y))
    }, 3000)
}

print(1, 3)

JavaScript运行主要依靠JavaScript引擎和运行环境,引擎将js源码翻译成计算机所理解的机器码,运行环境提供了一些与计算机底层通讯的API和运行实现。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK