搜索
首页web前端js教程JavaScript 的底层是如何工作的?

这篇文章的真正目的是以一种简单的方式介绍 JavaScript 在底层如何工作,这样即使是新程序员也能够掌握这个概念并可视化编写 JavaScript 时会发生什么。
首先,我想关注至少 3 个问题,这将有助于克服困难并内化背后的逻辑?
这些问题也是 Web 开发人员面试期间可能会被问到的问题,其中 JavaScript 意味着:

1。 JavaScript 是如何工作的?
2.解释一下同步和异步的区别?
3.或者解释一下这句话:JavaScript是单线程语言,可以是非阻塞的?

确实,编写程序并不需要了解 JavaScript 内部工作原理,但学习 JavaScript 是必要且至关重要的,以便了解背后发生的事情并感受您正在编写的内容,因此对于许多拥有多年经验的开发人员来说运营商不想知道这一点。

让我们先知道什么是程序?程序只是一组指令,告诉计算机要做什么以及如何执行任务。程序必须分配内存,否则,我们将无法在计算机上拥有变量,甚至无法保存文件。程序还应该解析(读取)并执行专用任务,并且所有操作都发生在内存中。

现在,JavaScript 拥有每个浏览器都实现的名为 JavaScript 引擎 的引擎。例如,在 Chrome 中,它称为 V8,在 Mozilla Firefox 中:Spider Monkey,Safari 浏览器:JavaScript Core Webkit。

下图为 google chrome 的 V8 引擎
How JavaScript works underneath the hood?

JavaScript 引擎内部发生了什么?

JavaScript 引擎(例如 Chrome 中的 V8)读取我们编写的 JavaScript 代码,并将其转换为浏览器的机器可执行指令。上图显示了 JavaScript 引擎的各个部分,它由两部分组成,即内存堆**和**调用堆栈

还需要注意的是,内存分配发生在内存堆中,而解析(读取)和执行发生在调用堆栈中。除此之外,内存堆告诉你你在程序中的位置。

让我们用 JS (JavaScript) 代码看看内存堆中的内存分配

const a = 4;  // now we allocated a memory. JS engine is going to remember
// that a has a value of 4. 

const Obj = {a, b, c };  // In memory, variable 'Obj' holds the object {a, b,c}

// The same as on array. the engine will remember values of the array
const Array = [1,2,3,4,5]

那么,上述代码在全局声明后会出现什么问题呢?

有一种叫做内存泄漏的东西。如上所述,变量声明发生在内存堆中,并且它的分配大小是有限的。当您继续声明非常大的数组而不是数字甚至未使用的全局变量时,这会填满内存并导致内存泄漏。你会听说全局变量很糟糕,因为当我们忘记清理时,我们会填满这个内存堆,最终浏览器将无法工作。

调用堆栈怎么样?

如果我们还记得的话,读取和执行脚本的是调用堆栈。我们用代码来说明一下吧。

const a = 4;  // now we allocated a memory. JS engine is going to remember
// that a has a value of 4. 

const Obj = {a, b, c };  // In memory, variable 'Obj' holds the object {a, b,c}

// The same as on array. the engine will remember values of the array
const Array = [1,2,3,4,5]

使用上面的代码,调用sack读取第一行console.log(“x”);并被放入调用堆栈中,JavaScript引擎识别出console.log已被添加,然后将其弹出到调用堆栈中,运行它并输出x。之后,它会删除第一个 console.log,因为它已完成运行,并将其放入第二个 console.log(“y”),将其添加到调用堆栈中,执行 y 并删除第二个 console.log。最后使用相同的过程获取console.log(“z”)。

这是最简单的演示,如果再复杂一点怎么办?举个典型的例子:


// Example Call Stak

console.log("x");
console.log("y");
console.log("z");

// Result in browser

// x
// y
// z
现在,根据调用堆栈,上面的代码发生了什么?让我们看看它将如何运行上面的代码块:

//调用堆栈

函数

example1() 将首先运行,然后函数 example2() 出现在调用堆栈的顶部并运行,在检查是否存在后打印出数字 7 作为输出其他要运行的代码。之后,它将开始按从 console.log(‘7’)、example2()、example1() 开始的顺序从调用堆栈中删除,并且调用堆栈现在为空。

>我们还记得这句话吗? JavaScript 是一种非阻塞的单线程语言。

单线程意味着它只有一个调用堆栈。它一次只能执行一件事,重要的是要强调调用堆栈是先进后出的,就像堆栈

其他语言可以有许多调用堆栈,即所谓的

多线程,拥有多个调用堆栈可能更有利,这样我们就不必一直等待任务。

>但是,为什么 JavaScript 被设计为单线程呢?

要回答这个问题,通常在单线程上运行代码非常容易,因为多线程环境中不会出现复杂的场景。你实际上有一件事情需要关心。在多线程中,可能会出现死锁之类的问题。有了这个理论,我们就很容易知道同步编程意味着什么

同步编程简单来说就是:执行第一行代码,执行第二行代码,执行第三行代码,等等......

更明确地说,这意味着 console.log(“y”) 无法运行,直到 console.log(“x”) 完成并且 console.log (“z”) 直到前两个都完成后才开始,因为它是一个 调用堆栈

程序员很可能会使用 stackoverflow.com 网站。这个名字是什么意思?出色地。让我们看看:

How JavaScript works underneath the hood?
堆栈溢出是如何发生的

上图显示了内存泄漏是如何发生的以及 JavaScript 引擎的内存堆如何溢出。这里,调用堆栈接收许多大于其大小的输入并溢出。

可以借助代码来演示堆栈溢出:

const a = 4;  // now we allocated a memory. JS engine is going to remember
// that a has a value of 4. 

const Obj = {a, b, c };  // In memory, variable 'Obj' holds the object {a, b,c}

// The same as on array. the engine will remember values of the array
const Array = [1,2,3,4,5]

请注意,JavaScript 是单线程的,一次只执行一个语句。 现在有一个问题:如果下面代码块中的console.log(“y”)有一个需要更长时间才能完成的大任务怎么办?例如循环遍历具有数千或数百万项的数组?那里会发生什么?

// Example Call Stak

console.log("x");
console.log("y");
console.log("z");

// Result in browser

// x
// y
// z

第一行将执行,并假设第二行有大量工作要执行,因此第三行将等待很长时间才能执行。在上面的示例中,这没有多大意义,但让我们想象一个执行繁重操作的大型网站,用户将无法执行任何操作。网站将冻结,直到任务完成并且用户在那里等待。对于表演来说这是一次糟糕的体验。

嗯,对于同步任务,如果我们有一个函数需要花费很多时间,那么它就会阻塞队列。所以,听起来我们需要一些非阻塞的东西。请记住我上面提到的那句话:JavaScript 是一种可以非阻塞的单线程语言。

理想情况下,在 JavaScript 中我们不会等待需要时间的事情。那么,我们该如何解决这个问题呢?

作为救援,有异步编程。那么,这是什么?

将异步视为一种行为。同步执行很棒,因为它是可预测的。在同步中,我们知道首先发生什么,接下来发生什么等等,但它可能会变慢。

当我们必须执行图像处理或通过网络发出请求(例如 API 调用)等操作时,我们使用的不仅仅是异步同步任务。

让我们看看如何用代码进行异步编程:

const a = 4;  // now we allocated a memory. JS engine is going to remember
// that a has a value of 4. 

const Obj = {a, b, c };  // In memory, variable 'Obj' holds the object {a, b,c}

// The same as on array. the engine will remember values of the array
const Array = [1,2,3,4,5]

现在,根据上面的代码,我们似乎跳过了第二行并执行第三行,并等待 3 秒输出结果。这是异步发生的。

为了理解这一点以及发生了什么,让我们使用下图。

How JavaScript works underneath the hood?
JavaScript 运行时环境

为了运行 JavaScript,我们需要的不仅仅是内存堆和调用堆栈。我们需要所谓的 JavaScript Run-Time,它是浏览器的一部分。它包含在浏览器中。在引擎之上,有一些称为Web API,回调队列事件循环,如图所示。

现在我们来讨论一下使用 setTimeout 函数的代码。

// Example Call Stak

console.log("x");
console.log("y");
console.log("z");

// Result in browser

// x
// y
// z

setTimeout 函数 是 Web API 的一部分,而不是 JavaScript 的一部分,相反,它是浏览器提供给我们用来进行异步编程的函数。因此,让我们提供更多详细信息以进行澄清。

调用堆栈: console.log(“x”) 进入调用堆栈,运行,然后我们将 console.log 发送到浏览器。之后,setTimeout(() =>{console.log(“y”);},3000);进入调用堆栈,因为第一个任务完成,然后转到第二个任务。

现在有件事,在阅读代码时,调用堆栈会检测到有一个 setTimeout 函数 已被设置,它不是 JavaScript 的一部分,而是 Web API 的一部分(参见图 JavaScript 运行时环境)并具有其特殊的特性。发生的情况是 setTimeout 触发 WEB API 并且由于 Web API 收到通知,该函数将从调用堆栈中弹出。

现在,Web API 启动一个三秒的计时器,知道它必须在 3 秒内完成任务。请记住这里,因为调用堆栈是空的,JavaScript 引擎继续到第 3 行,即 console.log(“z”);并执行它。这就是为什么我们得到结果 x,z 但我们在 Web API 中设置了三秒的 setTimeout。然后,三秒后,当时间限制结束时,setTimeout 运行并查看其中的内容,然后就完成了。完成后,Web API 将识别出它有 setTimeout 的 callback() 函数,并将其添加到 CALLBACK QUEUE 准备运行它。

我们来到最后一部分,即**事件循环*。这个函数会一直检查调用堆栈是否为空。当它为空并且 JavaScript 引擎中当前没有运行任何内容时,它将检查回调队列并使用 console.log(“z”) 找到我们的 **callback()* 函数,然后将其放入 CALL STACK 并运行。完成后,将其从调用堆栈中弹出。现在一切都是空的并得到结果 x z y。

结论:在这篇文章中,我们看到了很多有关幕后发生的事情的信息,以完全理解 JavaScript 逻辑以及同步和异步执行的任务。

希望这将帮助新的和高级 JavaScript 程序员享受在 ReactJS 或 AngularJS 等 JavaScript 相关框架中进行编码,因为这是理解高级逻辑的基础。

>快乐编码

参考文献

https://www.freecodecamp.org/news/how-javascript-works-behind-the-scenes。
https://www.simplilearn.com/tutorials/javascript-tutorial/callback-function-in-javascript#

以上是JavaScript 的底层是如何工作的?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
从网站到应用程序:JavaScript的不同应用从网站到应用程序:JavaScript的不同应用Apr 22, 2025 am 12:02 AM

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python vs. JavaScript:比较用例和应用程序Python vs. JavaScript:比较用例和应用程序Apr 21, 2025 am 12:01 AM

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C/C在JavaScript口译员和编译器中的作用C/C在JavaScript口译员和编译器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。