Если вы научились программировать с помощью JavaScript или Ruby, как многие из моих коллег-выпускников Flatiron, возможно, вы не знакомы с концепцией управления памятью. В конце концов, языки более высокого уровня управляют многими этими деталями «автоматически». Я взял это в кавычки, потому что бывают случаи, когда этот процесс может привести к ошибкам, и знание того, как он работает, может дать вам лучшее представление о том, как решить эти потенциальные проблемы.

В самом простом виде управление памятью можно представить так:

В JavaScript это выполняется очень просто, поскольку вы, вероятно, делаете это каждый раз, когда пишете код. Давайте рассмотрим простой пример:

В строке 2 мы Выделяем память. Объявление let x = {}; приведет к тому, что JavaScript автоматически выделит часть памяти, предназначенную для нашей переменной x.

В строках 3 и 4 мы Используем память. Мы получаем доступ к ключу first и присваиваем ему значение 1. Затем мы выводим объект x на консоль.

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

Итак, давайте перейдем к теме блога. В памяти есть два места, где хранятся переменные в JavaScript и большинстве других языков программирования. Стек времени выполнения (или сокращенно стек) и куча. Даже в таких языках, как C/C++, где вам приходится вручную освобождать память, переменные, хранящиеся в памяти стека, освобождаются автоматически.

Так что же определяет, в каком месте памяти хранится объявленная нами переменная? В таких языках, как Java или C/C++, их довольно легко отличить. Для Java и C++ любая переменная, объявленная с помощью оператора new, будет выделять память кучи. Любые другие переменные будут храниться в памяти стека. В C это еще более очевидно, так как нам нужно вызвать функцию malloc() для сохранения данных в куче. С JavaScript и другими языками более высокого уровня разница немного менее заметна, поскольку мы, как разработчики, не видим явных намеков на то, какие переменные помещаются в кучу или стек. Как правило, примитивные типы хранятся в стеке, а объекты/функции — в куче. Чуть более нюансированный ответ заключается в том, что когда переменная (ссылка на нее, а не только ее значение. См. мой пост об указателях!) сохраняется при нескольких вызовах функций, то, скорее всего, для нее выделено место в куче.

Итак, как это поможет мне как разработчику JavaScript?

Даже если вам никогда не придется беспокоиться о ручном выделении или освобождении памяти, знание того, как JavaScript управляет памятью под капотом, может привести вас в правильном направлении при попытке отладки вашего кода.

Например, если вы регулярно используете JavaScript, особенно React, в какой-то момент вы могли столкнуться с ошибкой, которая выглядит следующим образом:

Uncaught RangeError: Maximum call stack size exceeded

call stack на самом деле является нашей памятью стека! Это происходит, когда что-то в вашем коде выделяет слишком много памяти стека, скорее всего, из-за какого-то непреднамеренного бесконечного цикла.
Я считаю, что если вы потратите немного времени на изучение некоторых фундаментальных принципов, это не только поможет вам в разработке JavaScript, но и даст вам более глубокое понимание программирования в целом, не зависящее от языка!