百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

JS Runtime vs. JS Engine!Deno/Bun/Node是运行时!

xsobi 2024-12-16 17:05 1 浏览

家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

前几天发布了一篇介绍 JavaScript 引擎的文章,细数了全网最火的 10+ JavaScript 引擎。当时有朋友留言说漏掉了一个deno,但是我个人觉得 deno 更像是一个 JavaScript 运行时而不是 JavaScript 引擎。下面是已经发表的关于 JavaScript 引擎的文章传送门。

本文将重点聚焦 JavaScript 引擎和 JavaScript 运行时的区别,让大家更好的理解这两个核心概念。话不多说,直接开始!

1.JavaScript 引擎

1.1 什么是JavaScript 引擎

JavaScript 引擎是一个程序或解释器,它包括以下功能:

  • 读取 JavaScript 代码
  • 生成机器代码
  • 运行机器代码

JavaScript引擎依赖于 JavaScript 运行时(嵌入在JavaScript 运行时环境),如: Web 浏览器、Node.js,甚至 Java 运行时环境 (JRE)。 与任何其他解释器一样,JavaScript引擎的工作是读取和执行代码。

1.2 JavaScript 引擎如何工作

JavaScript 引擎组成

JavaScript 引擎有 6 个主要组成部分,作为一个整体协同工作。 下面将简要介绍各个部分如何连接以及如何协同工作。

  • 解析器 Parser :源代码被发送到解码器,解码器将 HTML 脚本标记内的内容解码为发送到解析器的 token, JavaScript 引擎会尝试避免立即解析不必要的代码以节省时间。
  • AST : 解析器根据接收到的标记创建节点, 通过节点创建了一个抽象语法树 (AST)。
  • 解释器 Interpreter : 逐行读取代码生成字节码,生成字节码后,删除AST并清理内存
  • Profiler : 监视和监视代码(Monitors and Watche)以优化代码。
  • 编译器Compiler :提前工作、翻译已编写代码并将其编译为机器可以读取的底层语言。
  • 优化代码:优化代码以让JavaScript运行时更快。

调用栈和内存堆

Call Stack 和 Memory Heap 都是 JS 引擎的重要组成部分。

  • Call Stack:调用堆栈跟踪代码位置,它使用先进后出的堆栈结构。
  • Memory Heap:内存堆存储和写入信息,包括分配、使用和删除内存。

调用堆栈从内存堆中调用一个函数,并在执行后将其从堆栈中删除。 当达到最大调用堆栈时,例如:无限循环,称为堆栈溢出。

比如下面的常见错误抛出:

Uncaught RangeError: Maximum call stack size exceeded

2. JavaScript 运行时

2.1 什么是JavaScript运行时

运行时是语言执行的环境,运行时通过使用队列、堆和堆栈等数据结构来促进存储函数、变量和管理内存。

JavaScript 运行时是一个扩展 JavaScript 引擎并提供附加功能的程序,因此它可以与外界交互。 此外,JS 运行时提供功能/API 来构建基于 Javascript 的软件。 这意味着浏览器和基于 JavaScript 的框架都有运行时,但根据它们的需要不同。

2.2 JavaScript 运行时如何工作

在谈论 JS 运行时及其工作原理时,需要讨论三个主要概念。

Web API

现代浏览器中有大量可用的 API,可以让开发者使用,比如一些最常见的 JS API :

  • 操作文档:DOM API 允许开发人员操作 HTML 和 CSS,让开发者创建、更改甚至删除 HTML 并将样式动态应用到网页。
  • 绘制和操作图形:Canvas API 和 Web Graphics Library API 允许以编程方式更新包含在 <canvas> 元素中的像素数据。
  • 从服务器获取数据 : Fetch API 提供了一个接口,用于通过使用请求和响应对象的通用定义来跨网络获取资源。

事件侦听器、计时函数和 AJAX 请求等功能都位于 Web API 容器中,直到触发操作。 当请求完成数据接收时,计时器到达设定时间或发生点击,都将触发回调函数发送到回调队列。

回调队列

回调队列按添加顺序存储从 Web API 发送的回调函数, 是一个先进先出的数据结构。回调函数将在队列中等待,直到调用堆栈为空,然后通过事件循环将它们推入堆栈。

事件循环

事件循环不断地监视调用堆栈和回调队列的状态。 如果堆栈为空,它将从回调队列中获取一个回调并将其放入调用堆栈,安排它执行。

通过将回调从 Web API 推送到回调队列,事件循环可以不断地将这些回调添加到调用堆栈。在这一点上,一定程度上可以认为 JavaScript 是异步运行的。

3.JavaScript 引擎和运行时协同工作

在代码执行之前需要做的第一件事是让 JavaScript 理解代码,这意味着根据 JavaScript 语言的语法分析代码并确定句子的格式。

function printDateTime() {
    console.log(greeting + ' Current Date/Time is ' + new Date());
}

var greeting = 'Hello there.';
var delay = 2000;
setTimeout(printDateTime, delay);

比如上面的代码:

  • 第 1~3 行是名称为 printDateTime 的函数声明。
  • 函数 printDateTime 不带参数。
  • 第 2 行是使用一个参数调用控制台对象的日志方法。
  • 第 2 行中的 new Date() 是对对象构造函数的调用。
  • 字符串 Current Date/Time 是将附加来自 new Date() 的输出对象。
  • 第 5 行和第 6 行是两个具有两个不同值的变量的声明和赋值。
  • 第 7 行是对带有两个参数的 setTimeout 函数的调用。

理解代码后,JavaScript 需要执行一些其他任务来执行代码,如:解析函数、参数值、管理返回值、排序函数调用、收集垃圾内存和准备机器指令, 这些都是JavaScript引擎的工作。

引擎完成其工作后,JavaScript 运行时开始运行。 如上所述,它检查回调队列,事件循环获取其中的任何内容以安排它执行。下图展示了 JavaScript 引擎和运行时的不同部分是如何协同工作的。


4.常见JavaScript 引擎与JavaScript 运行时

关于 JavaScript 引擎在前面的文章中其实已经重点介绍过,主要分为以下三种类型,比如:

  • 非常流行的通用JavaScript引擎: jerryscript、Duktape、MuJS、QuickJS、Espruino、V7、mJS等等
  • 特定场景的JavaScript引擎实现:如quickjs-emscripten 、wasm-jseval、wasmedge-quickjs、tiny-js、JScript .NET 、Tamarin、GNU Guile、Nashorn 、iv 、CL-JavaScript 、BESEN 、Hermes 、Graal.js 、Continuum 、Futhark、InScript 、JScript 、Jint 、Narcissus 、QtScript等等
  • 浏览器内置JavaScript引擎实现:如 V8 、SpiderMonkey 、JavaScriptCore (JSC) 、Chakra 、carakan等等

关于每一个JavaScript 引擎的重点介绍可以继续阅读我的另一篇文章《盘点全网最火的 10+ JavaScript引擎!QuickJS 只是其一!》。

细数了JavaScript 引擎外,大家再一起看看有哪些JavaScript 运行时。其实在前面的文章中也已经重点介绍过,比如:Nodejs、deno、Bun等等,下面是已经发布的关于三者的介绍系列文章。

更多JavaScript运行时的文章我已经在努力收集中,大家可以保持关注。

5.本文总结

本文主要和大家介绍 JavaScript 运行时和 JavaScript 引擎,同时说明了Deno/Bun/Node只是运行时。因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!

参考资料

https://medium.com/@misbahulalam/uncover-the-javascript-engine-vs-runtime-6556ef449634

https://algodaily.com/lessons/introduction-to-js-engines-and-runtimes

https://dev.to/sanderdebr/a-brief-explanation-of-the-javascript-engine-and-runtime-2idg

相关推荐

好用的云函数!后端低代码接口开发,零基础编写API接口

前言在开发项目过程中,经常需要用到API接口,实现对数据库的CURD等操作。不管你是专业的PHP开发工程师,还是客户端开发工程师,或者是不懂编程但懂得数据库SQL查询,又或者是完全不太懂技术的人,通过...

快速上手:Windows 平台上 cURL 命令的使用方法

在工作流程中,为了快速验证API接口有效性,团队成员经常转向直接执行cURL命令的方法。这种做法不仅节省时间,而且促进了团队效率的提升。对于使用Windows系统的用户来说,这里有一套详细...

使用 Golang net/http 包:基础入门与实战

简介Go的net/http包是构建HTTP服务的核心库,功能强大且易于使用。它提供了基本的HTTP客户端和服务端支持,可以快速构建RESTAPI、Web应用等服务。本文将介绍ne...

#小白接口# 使用云函数,人人都能编写和发布自己的API接口

你只需编写简单的云函数,就可以实现自己的业务逻辑,发布后就可以生成自己的接口给客户端调用。果创云支持对云函数进行在线接口编程,进入开放平台我的接口-在线接口编程,设计一个新接口,设计和配置好接口参...

极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:iN在之前和大家说过,在iN的家里是没有墙面开关的。...

window使用curl命令的注意事项 curl命令用法

cmd-使用curl命令的注意点前言最近在cmd中使用curl命令来测试restapi,发现有不少问题,这里记录一下。在cmd中使用curl命令的注意事项json不能由单引号包括起来json...

Linux 系统curl命令使用详解 linuxctrl

curl是一个强大的命令行工具,用于在Linux系统中进行数据传输。它支持多种协议,包括HTTP、HTTPS、FTP等,用于下载或上传数据,执行Web请求等。curl命令的常见用法和解...

Tornado 入门:初学者指南 tornados

Tornado是一个功能强大的PythonWeb框架和异步网络库。它最初是为了处理实时Web服务中的数千个同时连接而开发的。它独特的Web服务器和框架功能组合使其成为开发高性能Web...

PHP Curl的简单使用 php curl formdata

本文写给刚入PHP坑不久的新手们,作为工具文档,方便用时查阅。CURL是一个非常强大的开源库,它支持很多种协议,例如,HTTP、HTTPS、FTP、TELENT等。日常开发中,我们经常会需要用到cur...

Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介

本章涵盖使用Actix提供静态网页...

我给 Apache 顶级项目提了个 Bug apache顶级项目有哪些

这篇文章记录了给Apache顶级项目-分库分表中间件ShardingSphere提交Bug的历程。说实话,这是一次比较曲折的Bug跟踪之旅。10月28日,我们在GitHub上提...

linux文件下载、服务器交互(curl)

基础环境curl命令描述...

curl简单使用 curl sh

1.curl--help#查看关键字2.curl-A“(添加user-agent<name>SendUser-Agent<name>toserver)”...

常用linux命令:curl 常用linux命令大全

//获取网页内容//不加任何选项使用curl时,默认会发送GET请求来获取内容到标准输出$curlhttp://www.baidu.com//输出<!DOCTYPEh...

三十七,Web渗透提高班之hack the box在线靶场注册及入门知识

一.注册hacktheboxHackTheBox是一个在线平台,允许测试您的渗透技能和代码,并与其他类似兴趣的成员交流想法和方法。它包含一些不断更新的挑战,并且模拟真实场景,其风格更倾向于CT...