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

Как хранится объект в переменной?

2.3 Middle🔥 161 комментариев
#JavaScript Core

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

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

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

Хранение объектов в JavaScript: ссылочная модель

В JavaScript объекты (включая массивы, функции, даты и т.д.) хранятся в переменных не напрямую, а через ссылку (reference). Это фундаментальное отличие от примитивных типов (числа, строки, булевы значения), которые хранятся по значению (value).

Ключевые механизмы хранения

1. Стек (Stack) и Куча (Heap)

  • Стек используется для хранения:
    • Примитивных значений
    • Ссылок (указателей) на объекты
    • Вызовов функций (call stack)
  • Куча (Heap) — динамическая область памяти, где непосредственно размещаются объекты.

2. Пример демонстрации разницы

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

// Объект хранится по ссылке
let obj1 = { name: 'John' };
let obj2 = obj1; // Копируется ссылка, а не объект!
obj2.name = 'Jane';
console.log(obj1.name); // 'Jane' (оригинал изменился!)

Детальное описание процесса

1. Создание объекта

const user = { id: 1, name: 'Alex' };

При выполнении этого кода:

  • В куче создается объект {id: 1, name: 'Alex'}
  • В памяти выделяется уникальный адрес этого объекта (например, 0x123ABC)
  • В переменную user записывается не сам объект, а ссылка на адрес 0x123ABC

2. Копирование ссылок

const admin = user;

Теперь admin содержит ту же ссылку 0x123ABC. Обе переменные указывают на один и тот же объект в памяти.

3. Сравнение объектов

const objA = { value: 10 };
const objB = { value: 10 };
const objC = objA;

console.log(objA === objB); // false (разные ссылки!)
console.log(objA === objC); // true (одинаковые ссылки)

Практические следствия ссылочной модели

1. Мутабельность (изменяемость)

const products = [{ id: 1 }, { id: 2 }];
const cart = products; // Обе переменные ссылаются на один массив

cart.push({ id: 3 }); // Мутация через cart
console.log(products.length); // 3 (!) изменился и products

2. Создание независимых копий

Для создания настоящей копии объекта нужны специальные методы:

Поверхностное копирование:

const original = { a: 1, b: { inner: 2 } };
const shallowCopy = { ...original }; // Spread оператор
// Или: Object.assign({}, original)

shallowCopy.a = 99; // Не влияет на original
shallowCopy.b.inner = 100; // Меняет original.b.inner!

Глубокое копирование:

const deepCopy = JSON.parse(JSON.stringify(original));
// Или использовать библиотеки (lodash.cloneDeep)
// Или structuredClone() в современных браузерах

Особые случаи и оптимизации

1. Сборка мусора (Garbage Collection)

Объект удаляется из памяти, когда нет ни одной ссылки на него:

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

2. Внутренние оптимизации движков

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

  • Inline caching для быстрого доступа к свойствам
  • Hidden classes для эффективного представления объектов
  • Heap snapshots для отладки утечек памяти

Рекомендации для разработчиков

Работа с иммутабельностью:

// Плохо: мутация оригинального объекта
function updateUser(user) {
  user.updated = true; // Побочный эффект
}

// Хорошо: создание нового объекта
function updateUserSafe(user) {
  return { ...user, updated: true }; // Без побочных эффектов
}

Обнаружение утечек памяти:

  • Используйте WeakMap и WeakSet для хранения временных ссылок
  • Отслеживайте циклические ссылки
  • Используйте DevTools для анализа heap snapshots

Заключение

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

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

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

Как хранится объект в переменной? | PrepBro