搜索
首页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数据类型:浏览器和nodejs之间是否有区别?JavaScript数据类型:浏览器和nodejs之间是否有区别?May 14, 2025 am 12:15 AM

JavaScript核心数据类型在浏览器和Node.js中一致,但处理方式和额外类型有所不同。1)全局对象在浏览器中为window,在Node.js中为global。2)Node.js独有Buffer对象,用于处理二进制数据。3)性能和时间处理在两者间也有差异,需根据环境调整代码。

JavaScript评论:使用//和 / * * / * / * /JavaScript评论:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript:开发人员的比较分析Python vs. JavaScript:开发人员的比较分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

Python vs. JavaScript:选择合适的工具Python vs. JavaScript:选择合适的工具May 08, 2025 am 12:10 AM

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript:了解每个的优势Python和JavaScript:了解每个的优势May 06, 2025 am 12:15 AM

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

JavaScript的核心:它是在C还是C上构建的?JavaScript的核心:它是在C还是C上构建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript应用程序:从前端到后端JavaScript应用程序:从前端到后端May 04, 2025 am 12:12 AM

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

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

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

热门文章

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF

mPDF

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

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

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