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

Slice или splice мутирует массив

1.0 Junior🔥 301 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

Slice или splice мутирует массив

Ответ: SPLICE мутирует, SLICE не мутирует

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

  • slice() — создаёт новый массив, исходный не меняется (immutable)
  • splice()модифицирует исходный массив (mutable)

Сравнение методов

МетодМутирует оригиналВозвращаетСинтаксис
slice❌ НетНовый массивarray.slice(start, end)
splice✅ ДаУдалённые элементыarray.splice(start, deleteCount, ...items)

slice() — безопасный метод

const original = [1, 2, 3, 4, 5];

// slice() возвращает новый массив
const sliced = original.slice(1, 4);

console.log(sliced);    // [2, 3, 4]
console.log(original);  // [1, 2, 3, 4, 5] — не изменился!

// Позитивные индексы
const first3 = original.slice(0, 3); // [1, 2, 3]
const last2 = original.slice(-2);    // [4, 5]
const copy = original.slice();       // [1, 2, 3, 4, 5] — полная копия

Особенности slice:

  • Не включает конечный индекс (end)
  • Поддерживает отрицательные индексы
  • array.slice() без аргументов = полная копия (shallow copy)
  • Безопасен в функциональном программировании

splice() — опасный метод

const original = [1, 2, 3, 4, 5];

// splice() модифицирует исходный массив!
const removed = original.splice(1, 2); // Удалить 2 элемента начиная с индекса 1

console.log(removed);  // [2, 3] — удалённые элементы
console.log(original); // [1, 4, 5] — ИЗМЕНИЛСЯ!

// Вставка новых элементов
const arr = [1, 2, 5];
arr.splice(2, 0, 3, 4); // Вставить 3, 4 на позицию 2
console.log(arr); // [1, 2, 3, 4, 5]

// Замена элементов
const items = ['a', 'b', 'c', 'd'];
items.splice(1, 2, 'x', 'y'); // Заменить 'b', 'c' на 'x', 'y'
console.log(items); // ['a', 'x', 'y', 'd']

Параметры splice:

  • start — откуда начинать
  • deleteCount — сколько элементов удалить
  • ...items — что вставить на их место (опционально)

Практические примеры

Пример 1: Безопасное получение подмассива

function getRange(array, from, to) {
  // ✅ slice безопасен — не меняет оригинал
  return array.slice(from, to);
}

const data = [10, 20, 30, 40, 50];
const range = getRange(data, 1, 4); // [20, 30, 40]
console.log(data); // [10, 20, 30, 40, 50] — всё в порядке

Пример 2: Удаление элемента (опасно)

// ❌ Опасно — изменит исходный массив
function removeElement(array, index) {
  array.splice(index, 1); // Мутирует!
  return array;
}

const users = ['Alice', 'Bob', 'Charlie'];
removeElement(users, 1); // Удалит Bob
console.log(users); // ['Alice', 'Charlie'] — ИЗМЕНИЛСЯ!

// ✅ Безопасно — создаст новый массив
function removeElementSafe(array, index) {
  return array.filter((_, i) => i !== index);
  // или
  // return [...array.slice(0, index), ...array.slice(index + 1)];
}

const users2 = ['Alice', 'Bob', 'Charlie'];
const updated = removeElementSafe(users2, 1);
console.log(updated); // ['Alice', 'Charlie']
console.log(users2);  // ['Alice', 'Bob', 'Charlie'] — не изменился

Пример 3: Копирование массива

const original = [{id: 1}, {id: 2}];

// ✅ Shallow copy через slice
const copy1 = original.slice();

// ✅ Spread оператор (более современный)
const copy2 = [...original];

// ✅ Array.from
const copy3 = Array.from(original);

// ВАЖНО: это поверхностная копия!
copy1[0].id = 99;
console.log(original[0].id); // 99 — вложенные объекты всё ещё ссылаются!

// ✅ Глубокая копия
const deepCopy = JSON.parse(JSON.stringify(original));

Когда использовать каждый метод

Используй slice() когда:

  • Нужна часть массива без изменений исходного
  • Работаешь с функциональным программированием
  • Хочешь сделать копию массива
  • Пишешь чистые функции (pure functions)
  • Работаешь с React, Redux (immutability важна)
// React пример
const [items, setItems] = useState([1, 2, 3, 4, 5]);

const handleRemove = (index) => {
  // ✅ Правильно — создаём новый массив
  setItems(items.slice(0, index).concat(items.slice(index + 1)));
  // или
  setItems(items.filter((_, i) => i !== index));
};

Используй splice() когда:

  • Прямо хочешь изменить массив
  • Чистота функции не критична
  • Нужна максимальная производительность (избегаешь копирования)
  • Работаешь с DOM или состоянием, где мутация допустима
// Удаление элемента из списка
const todos = [{id: 1, title: 'Task 1'}, {id: 2, title: 'Task 2'}];
const index = todos.findIndex(t => t.id === 1);
if (index !== -1) {
  todos.splice(index, 1); // Быстро удаляет
}

Важные замечания

1. Тестирование поведения

const arr = [1, 2, 3];
const sliced = arr.slice();
sliced.push(4);

console.log(arr); // [1, 2, 3] — slice создал новый
console.log(sliced); // [1, 2, 3, 4]

const arr2 = [1, 2, 3];
arr2.splice(0, 0, 0); // Вставить 0 в начало

console.log(arr2); // [0, 1, 2, 3] — splice изменил

2. Производительность

// splice() быстрее для больших массивов
// но требует осторожности с мутацией

// slice() медленнее (копирование)
// но безопаснее для функционального кода

// Для React/Redux — всегда используй slice/filter/spread
// Мутация вызовет баги (React не обнаружит изменения)

3. Распространённая ошибка

// ❌ Ошибка: забыл, что splice мутирует
const items = [1, 2, 3, 4, 5];
function processItems(arr) {
  arr.splice(0, 1); // Думал, что возвращает новый массив
}

processItems(items);
console.log(items); // [2, 3, 4, 5] — сюрприз!

// ✅ Исправить
function processItems(arr) {
  return arr.slice(1); // Теперь безопасно
}

const processed = processItems(items);
console.log(processed); // [2, 3, 4, 5]
console.log(items); // [1, 2, 3, 4, 5] — не изменился

Заключение

Запомни простое правило:

  • slice = безопасно, создаёт новый массив
  • splice = опасно, изменяет исходный

В современном JavaScript (особенно с React, Redux, TypeScript) предпочитай slice, filter, map, spread operator — это делает код более предсказуемым и безопасным. splice используй только когда явно нужна мутация и ты уверен в её необходимости.

Slice или splice мутирует массив | PrepBro