Что такое переменная — и почему копия списка меняется вместе с оригиналом

Почти в каждом объяснении переменную называют коробкой: положил значение — забрал значение. Удобно, понятно и работает ровно до первого настоящего бага.
Потому что вот это ломает всю картинку:
const a = [1, 2, 3];
const b = a; // сделали "копию"
b.push(4);
console.log(a); // [1, 2, 3, 4] — оригинал тоже изменился!
Ты трогал b. Сломался a. Если переменная — коробка, объяснить это невозможно.
Давай возьмём картинку поточнее. С ней этот баг становится очевидным.
Переменная — это бирка, а не коробка
Представь чемодан. На ручке — бирка с именем.
Значение — это чемодан. Переменная — бирка, привязанная к нему. Имя написано на бирке, вещи лежат в чемодане.
Вся разница вот в чём: к одному чемодану можно привязать две бирки. И тогда неважно, за какую ты тянешь — чемодан один и тот же.
Строчка const b = a; не копирует чемодан. Она вешает вторую бирку на тот же самый.
Поэтому b.push(4) кладёт вещь в общий чемодан, а a честно показывает, что там внутри. Никакой магии — просто бирок две, а чемодан один.
Почему иногда всё-таки копируется
Тут новичка ждёт вторая ловушка. Иногда = ведёт себя ровно так, как ждёшь:
let x = 5;
let y = x;
y = 10;
console.log(x); // 5 — оригинал не тронут
Что случилось? Всё честно: числа, строки, true/false — простые значения. Их не кладут в чемодан, их пишут прямо на бирке. Скопировал бирку — скопировал и значение.
А вот списки, объекты и всё составное — это чемоданы. На бирке пишут только «где он стоит».
Отсюда правило на каждый день:
- число, строка, логическое —
=копирует значение, оригинал в безопасности; - список, объект, словарь —
=копирует только имя, чемодан остаётся общим.
Это устроено одинаково и в JavaScript, и в Python — двух языках, с которых чаще всего начинают. Так что выучил один раз — пригодится везде.
Как скопировать по-настоящему
Если нужна именно копия — её надо попросить явно.
В JavaScript:
const b = [...a]; // копия списка
const b = { ...obj }; // копия объекта
const b = structuredClone(a); // копия вместе с вложенными
В Python:
b = a.copy() # копия списка
import copy
b = copy.deepcopy(a) # копия вместе с вложенными
Почему две разные строчки? Потому что копия бывает мелкая и глубокая.
[...a] делает новый чемодан, но если внутри лежали другие чемоданы — в новый переложили их бирки, а не сами чемоданы. Верхний уровень отвязался, вложенные остались общими.
structuredClone и deepcopy копируют всё дерево целиком. Дороже по времени, зато честно и до конца.
Практическое правило: плоский список — хватит [...a]. Внутри объекты или вложенные списки — бери глубокую копию.
Где это выстрелит в коде от ИИ
Самое неприятное: такой баг не падает с ошибкой. Ничего не ломается, программа работает, данные просто тихо не те. Прочитать сообщение об ошибке тут не поможет — сообщения нет.
Выглядит это обычно так:
- отредактировал одну запись в списке — «поехали» все;
- сохранил черновик, изменил форму — черновик изменился вместе с ней;
- отфильтровал массив «в копию» — и потерял оригинал.
Агент такое пишет регулярно, особенно когда правит код кусками и не видит, откуда пришёл список. Поэтому, когда просматриваешь код, написанный ИИ, держи глаз на строчках вида const copy = original;. Слово copy в имени переменной ничего не копирует — копирует только явный вызов.
Переменная и константа — в чём разница?
const запрещает перевязывать бирку на другой чемодан. Но содержимое чемодана менять не мешает: const a = [1,2]; a.push(3) — законно. Запрещено только a = [9]. Именно поэтому пример в начале статьи работает, несмотря на const.
Это то же самое, что переменные окружения?
Нет, слово общее, а вещи разные. Переменная в коде живёт внутри программы. Переменная окружения задаётся снаружи — операционной системой или хостингом, и обычно хранит настройки и ключи.
Как называть переменные, чтобы потом не мучиться?
Имя должно отвечать на вопрос «что внутри», а не «какого оно типа». userEmail лучше, чем str1. И не бойся длинных имён: код читают в разы чаще, чем пишут.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.





