揭秘 JavaScript 调用堆栈:代码的实际运行方式

揭秘 javascript 调用堆栈:代码的实际运行方式

javascript 调用堆栈 是如何工作的,是每个前端开发人员在其职业生涯中至少问过一次的问题,在我看来,这个问题在大多数地方都没有得到解答,而且答案并不总是清晰或容易的去理解。这就是为什么我决定在这篇文章中讨论这个主题。

让我们从头开始吧。 javascript 引擎

同步逐行运行代码,每次执行函数时,它都会创建一个执行上下文(内存中的空间,用于存储仅存在于该函数内部的所有作用域属性)并添加函数到调用堆栈.

javascript 只执行位于

栈顶的函数的代码,当函数完成并返回其值时,引擎从调用堆栈中删除该函数并开始处理下一个函数。

调用堆栈为空时,javascript引擎继续在下一个全局上下文中运行代码,或者相同的,继续执行javascript文件根目录中的行,而不执行属于任何函数。

让我们逐行看一些示例:

const num1 = 2;const num2 = 5;function sum(a, b){return a + b;}const result= sum(num1, num2);console.log(result) // 7

这是一段非常简单的代码,定义了 2 个常量(num1 和 num2),然后定义了一个函数

sum 对 2 个数字求和并返回总和的结果。最后,创建常量 result,并将使用参数 num1num2 执行 sum结果分配给它。然后结果的值就会打印在控制台上。

如果您认为前面的解释太简单或太复杂并且没有解释任何东西,

请耐心等待,我们正在讲有趣的事情。

让我们逐行

看看 javascript 引擎在做什么。在第一行中,引擎创建一个标签num1并将存储在内存中2.

const num1 = 2;

第二行对标签

num2

执行相同的操作。它创建一个标签num2并在内存中存储值5.

const num2 = 5;

这意味着,每当

全局范围

内的人需要num2的值时,引擎就会更改标签并使用值5代替让我们继续下一行。下一行是

函数

sum。你认为引擎会做什么?你认为它会执行该函数还是将其添加到调用堆栈中? 不! 引擎要做的是存储一个名为sum的新标签,并将括号内的代码存储在内存中。或者相同的是,它将存储函数定义并将其分配给sum标签。

function sum(a, b){return a + b;}

如果我们能够

直观地看到到目前为止我们运行的代码的内存

,我们会看到这样的东西:

标签名称

记忆中的价值

num12num25总和函数定义下一行是

非常

有趣的一行。当 javascript 引擎到达下一行时,它会创建标签result,但此时,它还不知道需要为标签分配什么值,因为该值是执行函数的结果,所以首先,它需要执行函数,做函数需要做的任何事情,并从返回值中获取结果

const result= sum(num1, num2);

此时,引擎

将函数添加到调用堆栈

,并创建一个新的执行上下文,这是内存中的一个新空间,javascript可以存储args的值以及所有其他属性在函数内部而不与全局上下文发生冲突。

调用堆栈

总和全球首先,引擎在内存中创建标签

a

b,它们是给参数的名称,并分别分配参数25的值。 如果我们能看到这个特定时刻的记忆,我们会看到这样的东西:

立即学习“Java免费学习笔记(深入)”;

标签名称

记忆中的价值

a2b5返回2 + 5 = 7在这种情况下,函数非常简单,只返回

a

b之间的sum的值,因此引擎用arguments的值替换参数并将该值返回给全局执行上下文。最后,该函数从调用堆栈中删除,只保留全局上下文。

调用堆栈

全球此时,函数的结果被分配给标签

result

,我们可以通过控制台日志在控制台上打印该值。 让我们看看全局内存现在是什么样子:

立即学习“Java免费学习笔记(深入)”;

标签名称

记忆中的价值

num12num25总和函数定义结果7你注意到了吗?标签

结果

的值为7?而且sum里面仍然有函数定义。 我们来看看接下来的代码:

const num1 = 2;const num2 = 5;function sum(a, b){return a + b;}const result= sum(num1, num2);console.log(result) // 7function sumThreeNumbers = (x,y,z) => {return sum(x, y) + z}const result2 = sumThreeNumbers(4,6,2)console.log(result2) // 12

主要区别在于,现在我们有了一个新的

sumthreenumbers

函数,并且我们正在创建一个新的 result2 常量,并使用参数 462 分配运行函数 sumthreenumbers 的值让我们看看

运行嵌套函数时调用堆栈是如何工作的

如果我们在定义常量

result2

时跳转到该行,全局内存将如下所示:

标签名称

记忆中的价值

num12num25总和函数定义结果7三个数字的和函数定义就像前面的示例一样,javascript 引擎

不知道要为标签

result2分配什么值,要获取该值,首先需要使用参数执行函数sumthreenumbers。该函数添加到调用堆栈,并创建一个新的执行上下文。执行上下文将如下所示:

标签名称

记忆中的价值

x4y6z2因此 javascript 做的第一件事就是创建参数标签并分配参数提供的值。

现在让我们看一下我们的调用堆栈

立即学习“Java免费学习笔记(深入)”;

调用堆栈

三个数字的和全球如您所见,调用堆栈只有

sumthreenumbers

项(除了始终存在的全局上下文)。 为了能够获得结果值,

需要首先执行函数 sum

,因此引擎会将函数添加到调用堆栈并为 sum 函数创建一个新的执行上下文。

调用堆栈

总和三个数字的和全球由于 sum 函数位于

调用堆栈的顶部

,javascript 需要先运行sum才能继续运行sumthreenumbers这是查看函数 sum 的执行上下文的方式:

立即学习“Java免费学习笔记(深入)”;

标签名称

记忆中的价值

a4b6返回4 + 6 = 10如你所知,它将返回 _10 _并且将从调用堆栈中删除

立即学习“Java免费学习笔记(深入)”;

调用堆栈

三个数字的和全球javascript 将继续执行

sumthreenumbers

并且执行上下文将如下所示:

标签名称

记忆中的价值

x4y6z2返回10 + 2 = 12它将返回值

12

并从调用堆栈中删除。

调用堆栈

全球然后值

12

将被分配给属性result2并且值12将显示在控制台中。我希望这篇文章能帮助您了解

javascript调用堆栈是如何工作的

,如果是的话请留下评论和点赞。我在下一篇中见到你!

以上就是揭秘 JavaScript 调用堆栈:代码的实际运行方式的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1490611.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 13:18:25
下一篇 2025年12月19日 13:18:33

相关推荐

  • JavaScript 函数参数与实参:传递的是值还是引用?

    函数参数与实参之间的关系:解开 javascript 中的奥秘 最近,关于 javascript 中函数参数和实参之间的关系的问题引发了许多讨论。为了深入了解这一概念,让我们考虑一个示例: const a = [1, 2, 3];function test(x) { console.log(x ==…

    2025年12月19日
    000
  • 《瑞克和莫蒂》和《Clossures》:这些东西有什么共同点?

    那么,你好吗?我希望如此! 我试图在 leetcode 中解决一些编程问题,在其中一个挑战中,我遇到了一个很多人都难以理解的编程中非常重要的概念。 所以我决定在这里写下尝试以最好的方式解释闭包如何在javascript中工作。跟我来吧! 问题 我正在研究一个名为“counter”的挑战,其中我需要创…

    2025年12月19日
    000
  • JavaScript 主题

    以下是每个 JavaScript 主题的简要说明: 变量和数据类型:变量存储数据值,JavaScript 支持多种数据类型,如字符串、数字、布尔值、数组和对象。 var、let 和 const 用于声明变量。 函数(箭头函数、函数表达式):函数是设计用于执行特定任务的代码块。箭头函数 (=>)…

    2025年12月19日
    000
  • 初学者使用 JavaScript 时常犯的错误

    javascript 是一种超级有趣的语言,但让我们面对现实吧,当您刚开始使用时,它可能会有点棘手。作为一个仍在摸索中的人,我也犯过不少错误!因此,我想分享初学者在使用 javascript 时经常犯的五个常见错误 – 希望这可以帮助您避免它们。 1. 忘记声明变量 您在 javascr…

    2025年12月19日
    000
  • js如何看变量

    查看 JavaScript 中变量值的便捷方法包括:1. 使用 console.log() 方法将变量值打印到控制台中;2. 使用 alert() 方法弹出带有变量值的模态窗口;3. 使用 debugger 关键字暂停代码执行并打开调试器;4. 使用浏览器的 DOM 检查器查看网页上运行的 Java…

    2025年12月19日
    000
  • JS如何引用JS方法

    在 JavaScript 中引用 JS 方法并直接调用的方法有:使用函数名直接调用;使用对象或类的方法引用符引用;使用回调函数;使用事件侦听器;使用 bind() 方法绑定对象。 如何在 JS 中引用 JS 方法 直接调用: 如果方法在当前作用域中可用,可以使用函数名直接调用它。例如: functi…

    2025年12月19日
    000
  • 页面如何引用js变量

    有五种方法可以在页面中引用 JavaScript 变量:1. 使用全局变量;2. 使用函数作用域变量;3. 使用块级作用域变量;4. 通过 HTML 元素引用;5. 通过 window 对象引用。 页面如何引用 JS 变量 在 Web 开发中,引用 JavaScript 变量是一个常见的任务。有几种…

    2025年12月19日
    000
  • 如何写出js代码

    要编写 JavaScript 代码,首先需要文本编辑器或 IDE,推荐 Notepad++、Atom 和 Visual Studio Code。JavaScript 遵循 C 语言风格的语法,使用花括号表示块,分号表示语句结束。变量用 var 声明,数据类型包括字符串、数字、布尔值、数组和对象。函数…

    2025年12月19日
    000
  • js如何理解变量

    JavaScript 中的变量是用于存储数据的容器,可以使用 var、let 或 const 声明和赋值,具有作用域范围,可以存储字符串、数字、布尔值、对象和数组等数据类型,用于存储信息并进行操作,遵循最佳实践可确保代码整洁和可维护性。 理解 JavaScript 中的变量 变量是编程中用于存储数据…

    2025年12月19日
    000
  • js 如何定义变量

    JavaScript 中有三种定义变量的方法:var(全局作用域)、let(块级作用域)和 const(常量)。变量可以存储数字、字符串、布尔值、数组、对象、函数、undefined 和 null 等各种数据类型。 JavaScript 变量定义 在 JavaScript 中,变量用于存储数据,并通…

    2025年12月19日
    000
  • js是如何编译的

    JavaScript 是一种解释执行的语言,但为了提升性能,许多 JavaScript 引擎会采用编译过程:解析代码为语法树 (AST)优化 AST,包括常量提升、死代码消除和内联函数代码生成,将优化后的 AST 转换为机器代码执行编译后的机器代码编译的优点包括更快执行和更小代码大小;缺点包括更长的…

    2025年12月19日
    000
  • js如何使用this

    在 JavaScript 中,this 关键字表示当前执行上下文中的对象。这将取决于函数的调用方式,包括以下规则:全局作用域:指向 window 对象。对象方法:指向调用该方法的对象。构造函数:指向新创建的对象。 this在JavaScript中的使用 引言this是JavaScript中一个重要的…

    2025年12月19日
    000
  • js如何断点

    如何使用 JavaScript 断点?通过在 Chrome DevTools 中设置断点可暂停 JavaScript 执行,从而检查变量和堆栈调用。开发者可按以下步骤进行操作:设置断点:将鼠标悬停在代码行上并单击空心圆圈。暂停执行:当执行流达到断点时,代码将暂停。检查变量:在 “Vari…

    2025年12月19日
    000
  • typescript属性和变量区别

    TypeScript 中的属性和变量都用于存储数据,但有不同的特性:属性定义:属性是类或接口的成员,用于存储特定实例的数据。变量定义:变量是在函数、方法或块中声明的本地存储单元。关键区别在于作用域、可见性和使用方式。属性作用域于整个类或接口,而变量作用域仅限于其声明的范围。属性可见性可以由 publ…

    2025年12月19日
    000
  • 理解 JavaScript 对象和函数中的“this”

    js 对象作用域中的 this 关键字 在 javascript 中,了解 this 关键字的内容、方式和位置可能是编写实际有效的代码和在编码时抓狂的区别。 这个关键字 在javascript中,这是一个关键字(保留字),也就是说,它不能用作变量名。 在 javascript 代码中,这用于表示范围…

    2025年12月19日
    000
  • 了解 JavaScript 中的提升:综合指南

    javascript 中的提升 提升是一种行为,其中变量和函数声明在之前被移动(或“提升”)到其包含范围(全局范围或函数范围)的顶部代码被执行。这意味着您可以在代码中实际声明变量和函数之前使用它们。 变量提升 变量 用 var 声明的变量被提升到其作用域的顶部,但它们的值直到代码中发生赋值的地方才会…

    2025年12月19日
    000
  • Javascript面试题讲解-异步行为

    javascript 使用 settimeout 的异步行为 介绍 在本文中,我们将探索一段引人入胜的 javascript 代码,它演示了该语言的异步特性,特别是闭包和 settimeout 函数如何协同工作。如果您曾经对循环输出意外结果的原因感到困惑,那么您来对地方了! 关键概念 在深入研究代码…

    2025年12月19日
    000
  • JavaScript 的有趣之处以及 TypeScript 如何让它变得更好

    javascript 是一种我们都喜欢的语言,对吧?它灵活、轻便,并且可以随处运行。但老实说,尽管它很伟大,但它可能很奇怪。那种奇怪的感觉会让你在看到一些不应该起作用的东西后质疑自己的理智。 在本文中,我们将探讨 javascript 中的一些怪癖 – 那些在您最意想不到的时候让您感到惊…

    2025年12月19日
    000
  • 创建您自己的 npm 库

    介绍 react.js、three.js 等我们平时使用的优​​秀库其实都可以自己创建。我发布这篇文章是对加拿大一所大学创建图书馆课程的回顾。 先决条件 node.js 必须可用。安装 node.js 即可使用 npm。 将您自己的库发布到 npm 项目设置 首先,创建一个 npm 帐户。 npmj…

    2025年12月19日 好文分享
    000
  • JavaScript 提升解释以提高您的编码技能

    javascript 是一种经常会让新手感到困惑的语言。其中一种行为是提升,每个 javascript 开发人员都应该理解这一概念,以便编写更可预测的代码。在本文中,我们将探讨什么是提升、它如何与变量和函数配合使用,以及如何避免与之相关的陷阱。 什么是提升? 提升是指 javascript 将声明(…

    2025年12月19日
    000

发表回复

登录后才能评论
关注微信