← Все вопросы

Как скопировать массив в JavaScript, чтобы изменения не задевали оригинал?

Задан 20 месяцев назад318 просмотров2 ответа
9

Присвоил const copy = arr, добавил в copy элемент через push — и оригинальный массив тоже изменился! Думал, что сделал копию. Как правильно скопировать массив, чтобы он был независимым?

2 ответа

13
✓ Принятый ответ — помог автору

Тут классическое непонимание: const copy = arr не копирует массив, а лишь даёт второе имя на тот же самый массив в памяти. Меняешь по любому имени — меняется один и тот же массив.

const arr = [1, 2, 3];
const copy = arr;   // НЕ копия — та же ссылка
copy.push(4);
console.log(arr); // [1, 2, 3, 4] — оригинал тоже изменился!

Сделать настоящую (поверхностную) копию — несколько способов:

const arr = [1, 2, 3];

const c1 = [...arr];        // spread — самый частый
const c2 = arr.slice();     // slice без аргументов
const c3 = Array.from(arr); // Array.from

c1.push(4);
console.log(arr); // [1, 2, 3] — цел
console.log(c1);  // [1, 2, 3, 4]

Все три создают новый массив, и теперь изменения независимы.

Важная оговорка — это поверхностная копия. Если в массиве лежат объекты, копируются ссылки на них, а не сами объекты:

const users = [{ name: 'Аня' }];
const copy = [...users];
copy[0].name = 'Боб';
console.log(users[0].name); // 'Боб' — вложенный объект общий!

Для глубокой копии (с вложенными объектами) бери structuredClone:

const deep = structuredClone(users);
deep[0].name = 'Вера';
console.log(users[0].name); // не изменился

Вывод: для плоского массива чисел/строк хватит [...arr]. Есть вложенные объекты и их тоже меняешь — structuredClone.

4

То же правило «присваивание — это ссылка, а не копия» работает и для объектов:

const a = { x: 1 };
const b = a;
b.x = 99;
console.log(a.x); // 99 — один объект

Копия объекта — через spread { ...a } или Object.assign({}, a). Запомни: в JS массивы и объекты передаются по ссылке, а числа/строки/булевы — по значению. Отсюда почти все «магические» изменения оригинала.

Ваш ответ

Войдите, чтобы ответить на вопрос.