龙空技术网

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

高级前端进阶 500

前言:

此刻看官们对“qt可以用的ajax库”大概比较注意,你们都需要了解一些“qt可以用的ajax库”的相关内容。那么小编在网摘上搜集了一些关于“qt可以用的ajax库””的相关知识,希望姐妹们能喜欢,大家快快来学习一下吧!

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

高级前端‬进阶

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

《盘点全网最火的 10+ JavaScript引擎!QuickJS 只是其一!》《什么原因让我坚决选择 QuickJS ?》

本文将重点聚焦 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运行时更快。

JavaScript 引擎6个组成部分

调用栈和内存堆

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等等,下面是已经发布的关于三者的介绍系列文章。

《Node.js已死!Bun永生?》《前有Deno、后有Bun、Node.js已穷途末路?》《Node.js、Deno、Bun 6大典型场景性能大PK?》《Bun v0.5.7 发布!支持10+新特性!》

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

5.本文总结

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

参考资料

标签: #qt可以用的ajax库