До недавнего времени я слышал термин «стек» только в двух контекстах: в описаниях вакансий и проектов («ищу разработчика полного стека») или от имени Stack Overflow. Затем я услышал слово в отношении «стека вызовов», которое звучало достаточно важным, чтобы оправдать некоторые исследования. Немного самостоятельного обучения.

Моими двумя главными вопросами (и двумя вопросами, на которые я надеюсь ответить в этой статье) были: 1) что, черт возьми, такое «стек»? И, 2) что такое стек вызовов JavaScript и почему он важен?

После некоторых исследований я думаю, что разобрался с основами. Стек, стек вызовов, переполнение стека — все это связано. Я попытаюсь соединить точки.

Что такое стек?

Стек — это абстрактный тип данных (ADT), что в основном означает, что это идея о том, как данные могут вести себя и структурироваться. Это концепция.

Концепция, ну, стек. Представьте себе стопку тарелок: каждая кладется поверх другой, и вместе они образуют стопку.

Ключевой особенностью стека является то, что вы можете получить доступ только к элементам сверху. Стек обычно имеет только два метода для управления элементами: метод pop() удаляет самый верхний элемент из стека, а метод push() помещает новый элемент сверху.

Почему ограничение? Беглое чтение по этому вопросу показывает, что основной причиной является производительность. Чтобы убрать тарелку из середины нашей стопки, нам пришлось бы поднять тарелки сверху. Та же история и в коде: после того, как мы удалили элемент из середины (например) массива, мы должны сдвинуть назад те элементы, которые идут после него, что требует времени и ресурсов.

С технической точки зрения, методы pop() и push() (а также определение размера стека) являются операциями O(1), что является причудливым способом сказать: это занимает одинаковое количество времени независимо от размера ваших данных.

Однако добавление или удаление элементов из середины массива выполняется за O(n). Другими словами, время, необходимое для завершения, зависит от количества элементов (n), которые мы должны переместить, чтобы приспособиться к изменению. В массиве всего из нескольких элементов нет большой разницы между O(1) и O(n). Но при работе со структурами данных с множеством элементов (а это число n огромно) разница становится очевидной.

Стек вызовов JavaScript

Итак, где в нашем коде появляется стек? Хотя стек имеет сходство с обычными структурами данных, такими как массивы и связанные списки, технически это не стек. Вместо этого стек появляется во время выполнения нашего кода.

Время выполнения относится к той части жизненного цикла программы, когда выполняется код. Другими словами, это «рабочая фаза программы».

Вот довольно простой фрагмент кода:

function firstMessage() {
   console.log('First message')
}
function secondMessage() {
   firstMessage()
   console.log('Second Message')
}
secondMessage()

Когда этот код запускается, движок JavaScript просматривает его строка за строкой, и когда он находит действие, которое необходимо выполнить, он добавляет это действие в своего рода очередь или стек вызовов.

Давайте визуализируем это. Когда код выполняется впервые, стек вызовов содержит только один элемент, Main(), который представляет собой глобальную область, в которой выполняется код.

Затем движок JavaScript видит, что есть вызов secondMessage(), поэтому добавляет его в начало стека вызовов:

Но ждать! Сама функция secondMessage() вызывает функцию firstMessage(), поэтому она добавляется поверх стека.

Сама функция firstMessage() выполняет console.log:

Когда console.log('First message') завершен, он удаляется из стека. firstMessage() также удаляется из стека, так как он завершился успешно.

Наконец, secondMessage() выполняет свой собственный console.log:

После этого оба удаляются из стека, потому что их выполнение завершено.

Это на самом деле довольно просто, не так ли? JavaScript — это однопоточный язык, что означает, что он может выполнять только одну операцию за раз.

JavaScript — это однопоточный язык, что означает, что он может выполнять только одну операцию за раз.

Положительным моментом этого является то, что относительно легко визуализировать его работу. Недостатком является то, что если операция в стеке вызовов заняла, скажем, 15 минут, это пятнадцать минут для ожидания перед выполнением любых последующих операций в стеке.

Это то, что называется блокировкой: когда операция в стеке вызовов «задерживает» любые операции, следующие за ней, и понимание того, как работает стек вызовов JavaScript, может помочь предотвратить блокировку и оптимизировать производительность. наших приложений.

И если вы случайно запустите бесконечный цикл или каким-то образом перегрузите движок JavaScript до такой степени, что стек вызовов достигнет максимальной емкости, это называется переполнением стека. Так вот что означает название веб-сайта…

Как и в случае с большинством компьютерных тем, мы могли бы рассказать гораздо больше о стеке и стеке вызовов JS. Например, что происходит, когда в игру вступают асинхронные функции? Это выходит за рамки этой статьи для новичков, но я очень рекомендую это видео на эту тему, которое заставит вас почувствовать себя экспертом:

Сейчас я надеюсь, что вы лучше понимаете стек как абстрактный тип данных (идея,концепция, надежда, мечта ), а также стек вызовов JavaScript, который является важным способом применения этого типа данных к нашим приложениям JS.

До скорого!

Ссылки

1. Структуры данных (Википедия, отредактировано в апреле 2020 г.) 20 стак.»

2. Структуры данных и алгоритмы: стек(tutorialspoint.com)https://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm

3. Что такое стековая структура данных? (studytonight.com) https://www.studytonight.com/data-structures/stack-data-structure

4. Зачем изучать структуры данных и абстрактные типы данных (Академия RuneStone) https://runestone.academy/runestone/books/published/pythonds/Introduction/WhyStudyDataStructuresandAbstractDataTypes.html

5.Что такое структура данных стека и как она используется в JavaScript? (Git Connected, февраль 2020 г.) https://levelup.gitconnected.com/the-stack-data-structure-what-is-it-and-how-is-it-used-in-javascript- 23562fb8a590

7. Что такое, черт возьми, цикл обработки событий? (YouTube, октябрь 2014 г.) https://www.youtube.com/watch?v=8aGhZQkoFbQ&feature=emb_logo

8. Массивы большой O-нотации и вставки связанных списков (Stack Overflow, октябрь 2011 г.) https://stackoverflow.com/questions/7770569/big-o-notation-arrays-vs-linked- список-вставки