Возможно, вы работали над проектом в качестве начинающего разработчика JavaScript и столкнулись с уродливой красной ошибкой, говорящей: «Превышен максимальный размер стека вызовов», и вам стало любопытно, почему и что означает эта ошибка.
Что ж, вы находитесь в правильном месте, всегда следуйте своему любопытству, чтобы понять, почему возникает эта проблема и как мы можем ее решить, вы должны сначала понять, что такое стек вызовов и как он работает, тогда все будет ясно тебе.
Итак, что такое стек вызовов?
Проще говоря, это механизм интерпретатора для отслеживания вызовов функций и выполнения функций в вашем скрипте.
это означает, что когда вы определяете функцию в своем коде, а затем вызываете ее (вызываете ее), она добавляется в стек вызовов, как в примере ниже.
поэтому по своей форме стек вызовов похож на бар патронов, когда вы храните пули, уложенные друг на друга, как это используется в АК-47 в качестве примера. (если вы какое-то время играли в PUBG, вы меня поймете).
стек вызовов не хранит данные, он работает только с функциями, его задача — отслеживать вызовы функций.
механизм стека вызовов использует концепцию под названием LIFO (последний вошел первым), очень популярную концепцию в разработке программного обеспечения, это означает, что последняя функция, добавленная в стек, будет удалена первой.
Как это работает?
вот пример кода:
|function sayMyName(name) { console.log("name is"+ name); sayMyAge(24); } function sayMyAge(age) { console.log("my age is" + age); sayMyHobbies(["coding", "playing chess", "writing"]); } function sayMyHobbies(hobbies) { console.log("my hobbies are" + (...hobbies)); } sayMyName("sohaib"); // my name is sohaib // my age is 24 // my hobbies are coding,playing chess,writing
так будет работать в стеке вызовов
1- игнорировать все определения функций
2- вызвать функцию «sayMyName» и поместить ее в стек вызовов
3- выполнить то, что находится внутри функции sayMyName
4- вызвать функцию «sayMyAge» и поместить ее в стек вызовов.
5- выполнить то, что находится внутри функции «sayMyAge».
6- вызовите функцию «sayMyHobbies» и поместите ее в стек вызовов
7- выполнить то, что находится внутри функции «sayMyHobbies»
8- удалить функцию «sayMyHobbies» из стека
9- удалить функцию «sayMyAge» из стека
10- удалить функцию «sayMyName» из стека
всё, после этого стек будет пуст и он вернётся на ту строку, где был первый вызов, всё просто.
в нормальных условиях, когда у вас есть только одна функция, нет вложенных функций, это даже проще, он просто выталкивает/выталкивает функцию, и вы снова завершаете выполнение кода.
Где он находится?
слышали ли вы термин движок JavaScript или нет, стек вызовов является частью этого движка.
Чтобы быть ясным и избегать сложностей и усложнений, движок JavaScript — это среда, которая позволяет запускать JavaScript, будь то в браузере или на других платформах.
самые известные движки JavaScript — это V8, разработанная и поддерживаемая Google, используемая в браузере chrome и node.js, есть много других (обезьяна-паук в Mozilla Firefox, чакра в Microsoft edge ).
этот движок состоит из двух основных компонентов: кучи и стека вызовов.
В чем проблема «переполнения стека»:
стек вызовов имеет фиксированный размер количества накопленных функций в стеке.
это означает, что если вы продолжаете добавлять функции снова и снова в стек вызовов, не удаляя их из стека, это приведет к известной ошибке переполнение стека или на других языках переполнение буфера.
это может произойти из-за: бесконечного цикла, плохой реализации рекурсии, многих вложенных функций, это приведет к взрыву стека, поэтому ваша страница будет заблокирована и останется зависшей.
Как это решить?
это механизм, поэтому лучшее решение — научиться эффективно писать код и больше узнать о функциональном программировании.
- старайтесь избегать бесконечных циклов и научитесь писать правильный
- постарайтесь очень хорошо понять рекурсию в JavaScript, чтобы избежать взрыва стека.
- старайтесь избегать вложенных функций и тяжелых
- изучите асинхронное программирование на JavaScript и воспользуйтесь преимуществами среды выполнения браузера.
заключение
это было краткое введение в стек вызовов и проблему переполнения стека, конечно, по этой теме много информации, поэтому я приведу несколько ссылок, которые могут помочь вам понять эту тему. Приятных программистов, спасибо за чтение, не забудьте подписаться на меня в Twitter и LinkedIn.
Рекомендации
статьи:
- https://developer.mozilla.org/en-US/docs/Glossary/Call_stack
- https://dev.to/bipinrajbhar/how-javascript-works-under-the-hood-an-overview-of-javascript-engine-heap-and-call-stack-1j5o
- https://ui.dev/ultimate-guide-to-execution-contexts-hoisting-scopes-and-closures-in-javascript
видео: