Heap(куча) - Мы уже знакомы с кучей, и в первом уроке этого руководства говорили о том, что в куче хранятся все объекты и функции, и то, что здесь используется динамическое выделение памяти. Динамическое оно потому, что движок не знает, сколько ему понадобится памяти под тот или иной объект, а потому выделяет память по мере необходимости.
Stack
- Примитивные значения в свою очередь хранятся в контексте выполнения, а память для них выделяется на этапе создания до выполнения кода. Это связано с тем, что для примитивных значений существует фиксированный объем памяти. Это понятие часто упрощается до термина стек, чтобы избежать каждый раз упоминания конкретного контекста выполнения. Различные контексты выполнения взаимосвязаны и могут быть представлены структурой данных stack
(стек).
Теперь посмотрим на примере как это работает:
let a = 1;
Первом делом javascript движок создаст идентификатор a
- то есть переменную. Далее будет выделена память по определенному адресу(в моем случае это псевдо адрес) и после в память по этому адресу будет помещено значение.
javascript
в техническом плане, переменная представляет собой ссылку на место в памяти, где хранится значение. Это свойство языка, а не характеристика переменной как таковой.Добавим еще переменную и присвоем ей переменную a
.
let a = 1;
let b = a;
Теперь переменная b
ссылается на тот же адрес, что и переменная a
. Но что будет если мы перезапишем переменную a
?
let a = 1;
let b = a;
a = 2;
console.log(a); // 2
console.log(b); // 1
В таком случае выделяется новый кусочек памяти, после этого переменная a
указывает уже на новый адрес, с новым значением. В свою очередь, переменная b
указывает на старый адрес.
javascript
иммутабельны(неизменны), они хранятся в памяти как константы и не могут быть изменены после создания. Когда мы создаем переменную и присваиваем ей значение 1
, это значение будет храниться в памяти как константа с типом number
. При изменении выделяется новый кусочек памяти в котром будет содержаться новое значение.Теперь посмотрим на объект.
const anime = {
name: 'gintama',
seasons: 8
};
В таком случае у нас в стеке создается идентификатор с новым адресом в памяти, который хранит в себе адрес на объект в куче. Теперь попробуем создать еще объект и присвоим ему объект anime
.
const anime = {
name: 'gintama',
seasons: 8
};
const newAnime = anime;
newAnime.name = 'trigun';
console.log(anime.name); // trigun
console.log(newAnime.name); // trigun
В таком случае, новая переменная, как и в примере со значениями, будет ссылаться на тот же адрес в стеке, который, в свою очередь, уже ссылается на адрес в куче. При этом, неважно, что мы объявили объект через const
, мы не меняем значение внутри переменной newAnime
- значение этой переменной это ссылка на объект в куче и эта ссылка остается нетронутой, мы меням значение, которое находится в куче.