← Назад к вопросам

Как хранятся ссылочные типы данных?

2.2 Middle🔥 121 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизм хранения ссылочных типов данных

В JavaScript (и многих других языках) система хранения данных делится на примитивные (number, string, boolean, null, undefined, symbol, bigint) и ссылочные типы (объекты, массивы, функции, Date, RegExp и т.д.). Ключевое различие заключается в механизме их хранения в памяти.

Принципиальная разница в хранении

Примитивные типы хранятся непосредственно в стеке (stack) как значения. При присваивании переменной с примитивным типом другой переменной происходит копирование значения:

let a = 10;
let b = a; // Копируется значение 10
b = 20;
console.log(a); // 10 (не изменилось)
console.log(b); // 20

Ссылочные типы хранятся по совершенно другой схеме:

  1. Сама структура данных (объект) размещается в куче (heap) - динамической области памяти
  2. В стеке хранится ссылка (адрес памяти, pointer) на место в куче
  3. При присваивании копируется именно ссылка, а не сам объект

Детальный процесс хранения

// Создание объекта
let obj1 = { name: 'John', age: 30 };

/*
Что происходит в памяти:
1. В КУЧЕ создаётся объект: { name: 'John', age: 30 }
2. В СТЕКЕ создаётся переменная obj1, содержащая АДРЕС (ссылку) 
   на объект в куче
3. Ссылка - это фактически указатель на ячейку памяти
*/

let obj2 = obj1; // Копируется ССЫЛКА, а не объект!

obj2.age = 31; // Меняем свойство через obj2

console.log(obj1.age); // 31 - изменился исходный объект!
console.log(obj1 === obj2); // true - обе переменные ссылаются на один объект

Ключевые особенности работы с ссылочными типами

Копирование ссылок, а не значений:

const users = [{ name: 'Alice' }, { name: 'Bob' }];
const team = users; // team и users ссылаются на один массив
team.push({ name: 'Charlie' });
console.log(users.length); // 3 - исходный массив изменился!

Сравнение ссылок:

const a = { value: 10 };
const b = { value: 10 };
const c = a;

console.log(a === b); // false - разные ссылки
console.log(a === c); // true - одинаковые ссылки
console.log(a.value === b.value); // true - значения свойств одинаковы

Особенности передачи в функции:

function updateName(person) {
  person.name = 'Updated'; // Изменяет оригинальный объект
  person = { name: 'New' }; // Переназначает локальную ссылку
}

const user = { name: 'Original' };
updateName(user);
console.log(user.name); // 'Updated' - объект был изменён

Управление памятью и сборка мусора

JavaScript использует автоматическую сборку мусора (garbage collection). Объект в куче удаляется, когда на него больше нет ссылок:

let data = { large: 'объект' };
data = null; // Старый объект теперь доступен для сборки мусора
// Если других ссылок на { large: 'объект' } нет, память будет освобождена

Практические следствия для разработчика

Глубокое vs поверхностное копирование:

// Проблема поверхностного копирования
const original = { 
  user: { name: 'John' },
  scores: [10, 20, 30]
};

const shallowCopy = { ...original }; // spread operator
shallowCopy.user.name = 'Mike'; // Меняет оригинал!
shallowCopy.scores.push(40); // Меняет оригинал!

// Решение: глубокое копирование
const deepCopy = JSON.parse(JSON.stringify(original)); // Ограниченный способ
// Или использование structuredClone() в современных средах
const betterDeepCopy = structuredClone(original);

Иммутабельность и производительность:

  • Изменение больших объектов создаёт нагрузку на память
  • Рекомендуется использовать иммутабельные обновления:
// Вместо прямого изменения
const newState = {
  ...oldState,
  user: {
    ...oldState.user,
    age: 31
  }
};

Особые случаи:

  • Циклические ссылки могут предотвратить сборку мусора
  • Глобальные переменные хранят объекты в течение всей жизни приложения
  • Замыкания могут сохранять ссылки на объекты дольше ожидаемого

Оптимизации в движках JavaScript

Современные движки (V8, SpiderMonkey) применяют оптимизации:

  • Inline caching для быстрого доступа к свойствам
  • Hidden classes для эффективного представления объектов
  • Generational garbage collection для минимизации пауз

Понимание механизма хранения ссылочных типов критически важно для:

  1. Отладки неожиданных изменений данных
  2. Оптимизации использования памяти
  3. Предотвращения утечек памяти
  4. Реализации корректного сравнения объектов
  5. Работы с состояниями в React, Vue и других фреймворках

Это фундаментальное знание отделяет junior разработчика от middle/senior, так как позволяет прогнозировать поведение системы и писать более эффективный, безопасный и поддерживаемый код.