javascript 堆栈_JavaScript调用堆栈-它是什么以及为什么它是必需的

javascript 堆栈

The JavaScript engine (which is found in a hosting environment like the browser), is a single-threaded interpreter comprising of a heap and a single call stack. The browser provides web APIs like the DOM, AJAX, and Timers.

JavaScript引擎(可在诸如浏览器之类的托管环境中找到)是一个单线程解释器,由堆和单个调用堆栈组成。 浏览器提供了DOM,AJAX和Timers等Web API。

This article is aimed at explaining what the call stack is and why it is needed. An understanding of the call stack will give clarity to how “function hierarchy and execution order” works in the JavaScript engine.

本文旨在说明什么是调用堆栈以及为什么需要调用堆栈。 对调用栈的理解将使“函数层次结构和执行顺序”在JavaScript引擎中的工作方式更加清晰。

The call stack is primarily used for function invocation (call). Since the call stack is single, function(s) execution, is done, one at a time, from top to bottom. It means the call stack is synchronous.

调用堆栈主要用于函数调用(调用)。 由于调用堆栈是单个的,因此函数的执行从上到下一次完成。 这意味着调用堆栈是同步的。

The understanding of the call stack is vital to Asynchronous programming (which we will look at in a later article).

对调用栈的理解对于异步编程至关重要(我们将在以后的文章中介绍)。

In Asynchronous JavaScript, we have a callback function, an event loop, and a task queue. The callback function is acted upon by the call stack during execution after the call back function has been pushed to the stack by the event loop.

在异步JavaScript中,我们有一个回调函数,一个事件循环和一个任务队列。 在事件循环将回调函数推到堆栈之后,回调函数将在执行期间由调用堆栈执行。

But before we jump the gun, let us first attempt to answer the question - What is the call stack?

但是,在我们开枪之前,让我们首先尝试回答问题-调用堆栈是什么?

At the most basic level, a call stack is a data structure that uses the Last In, First Out (LIFO) principle to temporarily store and manage function invocation (call).

在最基本的级别上,调用堆栈是一种数据结构,它使用后进先出(LIFO)原理临时存储和管理函数调用(调用)。

Let’s break down our definition:

让我们打破我们的定义:

LIFO: When we say that the call stack, operates by the data structure principle of Last In, First Out, it means that the last function that gets pushed into the stack is the first to be pop out, when the function returns.

LIFO:当我们说调用堆栈是按照后进先出的数据结构原理进行操作时,这意味着当函数返回时,被压入堆栈的最后一个函数是第一个弹出的函数。

Let us take a look at a code sample to demonstrate LIFO by printing a stack trace error to the console.

让我们看一下通过将堆栈跟踪错误打印到控制台来演示LIFO的代码示例。

function firstFunction(){
  throw new Error('Stack Trace Error');
}

function secondFunction(){
  firstFunction();
}

function thirdFunction(){
  secondFunction();
}

thirdFunction();

When the code is run, we get an error. A stack is printed showing how the functions are stack on top each other. Take a look at the diagram.

运行代码时,我们会收到错误消息。 会打印出一个堆栈,说明如何将功能堆叠在一起。 看一下该图。

You will notice that the arrangement of the functions as a stack begins with the firstFunction() (which is the last function that got into the stack, and is popped out to throw the error), followed by the secondFunction(), and then the thirdFunction() (which is the first function that gets pushed into the stack when the code is executed).

您会注意到,函数作为堆栈的排列以firstFunction() (它是进入堆栈的最后一个函数,然后弹出弹出错误)的位置开始,然后是secondFunction() ,然后是thirdFunction() (这是在执行代码时被压入堆栈的第一个函数)。

Temporarily store: When a function is invoked (called), the function, its parameters, and variables are pushed into the call stack to form a stack frame. This stack frame is a memory location in the stack. The memory is cleared when the function returns as it is pop out of the stack.

临时存储 :调用(调用)一个函数时,该函数,其参数和变量被推入调用堆栈以形成堆栈框架。 该堆栈帧是堆栈中的内存位置。 当函数返回时(从栈中弹出),将清除内存。

Manage function invocation (call): The call stack maintains a record of the position of each stack frame. It knows the next function to be executed (and will remove it after execution). This is what makes code execution in JavaScript synchronous.

管理功能调用(调用) :调用堆栈维护每个堆栈帧位置的记录。 它知道下一个要执行的功能(并在执行后将其删除)。 这就是使JavaScript中的代码执行同步的原因。

Think of yourself standing on a queue, in a grocery store cash point. You can only be attended to after the person in front of you have been attended to. That’s synchronous.

想想自己站在杂货店现金点的队列中。 只有当您面前的人受到照顾后,您才能得到照顾。 那是同步的。

This is what we mean by “manage function invocation”.

这就是我们所说的“管理功能调用”。

调用堆栈如何处理函数调用? (How does the call stack handle function calls?)

We will answer this question by looking at a sample code of a function that calls another function. Here is the example code:

我们将通过查看调用另一个函数的函数的示例代码来回答这个问题。 这是示例代码:

function firstFunction(){
  console.log("Hello from firstFunction");
}

function secondFunction(){
  firstFunction();
  console.log("The end from secondFunction");
}

secondFunction();

This is what happens when the code is run:

这是运行代码时发生的情况:

1. When secondFunction() gets executed, an empty stack frame is created. It is the main (anonymous) entry point of the program.2. secondFunction() then calls firstFunction()which is pushed into the stack.3. firstFunction() returns and prints “Hello from firstFunction” to the console.4. firstFunction() is pop off the stack.5. The execution order then move to secondFunction().6. secondFunction() returns and print “The end from secondFunction” to the console.7. secondFunction() is pop off the stack, clearing the memory.

1.执行secondFunction() ,将创建一个空的堆栈框架。 它是程序的主要(匿名)入口点。 secondFunction()然后调用firstFunction() ,该函数被压入firstFunction()firstFunction()返回并将“ Hello from firstFunction”打印到控制台。4。 firstFunction()从堆栈中弹出5。 然后,执行顺序移至secondFunction() .6。 secondFunction()返回并将“ secondFunction的结尾”打印到控制台。7。 secondFunction()从堆栈中弹出,清除内存。

是什么导致堆栈溢出? (What causes a stack overflow?)

A stack overflow occurs when there is a recursive function (a function that calls itself) without an exit point. The browser (hosting environment) has a maximum stack call that it can accomodate before throwing a stack error.

当存在没有出口点的递归函数(调用自身的函数)时,将发生堆栈溢出。 浏览器(宿主环境)具有最大的堆栈调用,在引发堆栈错误之前,它可以适应。

Here is an example:

这是一个例子:

function callMyself(){
  callMyself();
}

callMyself();

The callMyself() will run until the browser throws a “Maximum call size exceeded”. And that is a stack overflow.

callMyself()将一直运行,直到浏览器抛出“超出最大呼叫大小”为止。 那就是堆栈溢出。

综上所述 (In summary)

The key takeaways from the call stack are:1. It is single-threaded. Meaning it can only do one thing at a time.2. Code execution is synchronous.3. A function invocation creates a stack frame that occupies a temporary memory.4. It works as a LIFO — Last In, First Out data structure.

调用堆栈的主要收获是:1.。 它是单线程的。 一次只能做一件事2。 代码执行是同步的3。 函数调用会创建一个占用临时内存的堆栈帧4。 它用作LIFO —后进先出数据结构。

We have used the call stack article to lay the foundation for a series we will be looking at on Asynchronous JavaScript (which we will be looking at in another article).

我们已经使用了调用栈文章为我们将在异步JavaScript上进行学习的系列奠定了基础(我们将在另一篇文章中进行介绍)。

All code samples can be found in this GitHub repo.

所有代码示例都可以在此GitHub存储库中找到。

Thank you for reading. If this article was helpful please give it some claps ? so others can find it. I will like to read your comments also.

感谢您的阅读。 如果这篇文章有帮助,请给它一些鼓掌? 以便其他人可以找到它。 我也想阅读您的评论。

翻译自: https://www.freecodecamp.org/news/understanding-the-javascript-call-stack-861e41ae61d4/

javascript 堆栈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误的意思是 JavaScript 堆内存不足。这意味着你的程序尝试使用更多内存,但是电脑上可用的内存不足以满足需求。 这种情况通常发生在你的程序中存在内存泄露(memory leak)或者你的程序使用了过多的内存。 解决方法可能包括: - 寻找并修复内存泄露 - 优化你的程序,减少内存使用 - 尝试使用更大的内存限制来运行你的程序(例如,使用 `node --max-old-space-size=4096 script.js` 运行你的程序) ### 回答2: "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory" 是一个 JavaScript 运行时错误,意味着 JavaScript 堆内存耗尽,无法分配更多的内存。 这个错误通常发生在当 JavaScript 代码尝试分配大量的内存时,但 JavaScript 堆的大小限制不足以满足需求时。可能的原因包括: 1. 代码中存在大量的变量、对象或数据结构,导致内存消耗过大。 2. 处理大型文件或大数据集时,内存耗用超过 JavaScript 堆的限制。 3. 程序出现了内存泄漏,即过多的内存资源没有被及时释放。 解决此问题的方法包括: 1. 优化代码:检查代码中是否存在内存使用不当的情况,如多余的变量、不必要的对象或数组等。确保及时释放不再使用的资源。 2. 增加内存限制:通过命令行参数或配置文件,增加 Node.js 的默认内存限制。例如:"node --max-old-space-size=4096 script.js" 将内存限制增加到 4GB。 3. 分块处理大型文件或数据集:将大型任务分解成小块,逐步处理,避免一次加载所有数据导致内存耗尽。 4. 检查内存泄漏:使用内存分析工具,如 Node.js 自带的 heapdump 库,来检测和修复内存泄漏问题。 综上所述,“FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory” 错误表示 JavaScript 堆内存不足,需要根据具体情况优化代码、增加内存限制或解决内存泄漏问题。 ### 回答3: "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory" 这个错误是指JavaScript堆内存耗尽,导致分配失败。当JavaScript代码执行时,它需要在内存中分配一定的空间来存储变量、对象和函数等数据。如果代码执行过程中需要分配的内存超出了JavaScript堆的限制,就会发生这个错误。 出现这个错误的原因可能有以下几种情况: 1. 内存泄漏:代码中存在内存泄漏的问题,即创建的变量或对象没有被正确释放,导致内存不断增加,最终耗尽堆内存。 2. 数据过大:代码需要处理的数据量过大,超过了JavaScript堆内存的限制。 3. 递归调用:代码中递归调用的层数过多,导致堆栈溢出,最终堆内存耗尽。 解决这个错误可以采取以下一些措施: 1. 检查代码中的内存泄漏问题,确保创建的变量、对象等在使用完后及时释放。可以使用工具来检测和修复内存泄漏问题。 2. 优化代码,减少不必要的数据量处理,如使用分页加载数据,分批处理大数据量等方法来降低内存消耗。 3. 如果是递归调用导致的堆栈溢出,可以考虑使用迭代替代递归,或者通过增加堆栈大小来解决问题。 4. 增加Node.js的堆内存限制,可以在启动命令中通过"--max-old-space-size"参数设置堆内存的大小。例如,使用"--max-old-space-size=4096"将堆内存增加到4GB。 总之,当出现"FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory"错误时,我们需要分析具体的情况,并根据问题的原因采取相应的解决措施,以确保代码能够正常执行而不造成内存耗尽。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值