$ sudo teach IT
МОДУЛЬ 5 · УРОК 2

Изменение массивов: push, pop, splice, slice

Знать как создать массив — это начало. Но работа с данными — это постоянные добавления, удаления, вырезки. Сегодня изучим полный арсенал методов для изменения массивов.

⏱ ~30 минут 🎓 Для новичков 🔧 Методы массивов

➕ push() и pop() — работа с концом массива

Представьте стопку тарелок. Когда добавляете тарелку — кладёте сверху. Когда убираете — снимаете сверху. Именно так работают push и pop: они работают с концом массива.

📥
push() — добавить в конец

Добавляет один или несколько элементов в конец массива. Возвращает новую длину массива.

📤
pop() — убрать с конца

Удаляет последний элемент из массива. Возвращает удалённый элемент.

let cart = ["яблоко", "хлеб"];
console.log(cart); // ["яблоко", "хлеб"]

// push: добавляем в конец
let newLength = cart.push("молоко");
console.log(cart);      // ["яблоко", "хлеб", "молоко"]
console.log(newLength); // 3 — push возвращает новую длину

// push с несколькими аргументами сразу
cart.push("масло", "сыр");
console.log(cart); // ["яблоко", "хлеб", "молоко", "масло", "сыр"]

// pop: удаляем с конца
let removed = cart.pop();
console.log(removed); // "сыр"    — pop возвращает удалённый элемент
console.log(cart);    // ["яблоко", "хлеб", "молоко", "масло"]

💡 Запомните разницу: push() возвращает новую длину массива, а pop() возвращает сам удалённый элемент. Это важно, если нужно использовать результат.

↔️ unshift() и shift() — работа с началом массива

Те же операции, но для начала массива. Очередь в магазине: новый человек приходит в хвост, а обслуживают с головы — так работают shift и unshift.

⏫
unshift() — добавить в начало

Добавляет элементы в начало массива. Все существующие элементы сдвигаются вправо.

⏬
shift() — убрать с начала

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

let queue = ["Иван", "Мария"];
console.log(queue); // ["Иван", "Мария"]

// unshift: добавляем в начало
queue.unshift("Алексей");
console.log(queue); // ["Алексей", "Иван", "Мария"]

// unshift с несколькими аргументами
queue.unshift("Первый", "Второй");
console.log(queue); // ["Первый", "Второй", "Алексей", "Иван", "Мария"]

// shift: удаляем первый элемент
let served = queue.shift();
console.log(served); // "Первый" — shift возвращает удалённый элемент
console.log(queue);  // ["Второй", "Алексей", "Иван", "Мария"]

⚠️ Производительность: push/pop быстрее, чем unshift/shift. При добавлении/удалении в начало JS вынужден сдвинуть все остальные элементы. При работе с концом — сдвигов нет. Для больших массивов это заметно.

Сравнительная таблица

push(el)

Добавить в КОНЕЦ

pop()

Удалить с КОНЦА

unshift(el)

Добавить в НАЧАЛО

shift()

Удалить с НАЧАЛА

🔪 splice() — универсальный нож

splice() — самый мощный метод для изменения массива. Он умеет три вещи: удалять элементы, вставлять новые и заменять существующие. Всё это на любой позиции в массиве.

Синтаксис: arr.splice(start, deleteCount, item1, item2, ...)

  • start — с какого индекса начать (отрицательный — считать с конца)
  • deleteCount — сколько элементов удалить (0 = только вставка)
  • item1, item2... — элементы для вставки на это место (необязательно)

Возвращает массив удалённых элементов.

Удаление элементов

let colors = ["красный", "синий", "зелёный", "жёлтый", "фиолетовый"];

// Удалить 2 элемента начиная с индекса 1
let removed = colors.splice(1, 2);
console.log(removed); // ["синий", "зелёный"] — что удалили
console.log(colors);  // ["красный", "жёлтый", "фиолетовый"]

// Удалить всё с индекса 2 до конца
let tail = colors.splice(2);
console.log(tail);   // ["фиолетовый"]
console.log(colors); // ["красный", "жёлтый"]

Вставка элементов (без удаления)

let letters = ["А", "Б", "Д", "Е"];

// Вставить "В" и "Г" на позицию 2, ничего не удаляя (deleteCount = 0)
letters.splice(2, 0, "В", "Г");
console.log(letters); // ["А", "Б", "В", "Г", "Д", "Е"]

Замена элементов

let team = ["Иван", "Мария", "УСТАРЕЛ", "Алексей"];

// Заменить элемент с индексом 2: удалить 1, вставить "Дмитрий"
team.splice(2, 1, "Дмитрий");
console.log(team); // ["Иван", "Мария", "Дмитрий", "Алексей"]

Отрицательный start — считаем с конца

let nums = [1, 2, 3, 4, 5];

// Удалить последние 2 элемента
nums.splice(-2, 2);
console.log(nums); // [1, 2, 3]

✂️ slice() — вырезаем копию

slice() не изменяет оригинальный массив — он возвращает новый массив, который является копией части исходного. Это ключевое отличие от splice.

Синтаксис: arr.slice(start, end)

  • start — с какого индекса начать (включительно)
  • end — до какого индекса (НЕ включительно)
  • Оба параметра могут быть отрицательными
let letters = ["А", "Б", "В", "Г", "Д", "Е"];

// Вырезать с индекса 1 до 4 (4 не включается)
let part = letters.slice(1, 4);
console.log(part);    // ["Б", "В", "Г"]
console.log(letters); // ["А", "Б", "В", "Г", "Д", "Е"] — оригинал не изменился!

// Начать с индекса 3 до конца (без второго аргумента)
let tail = letters.slice(3);
console.log(tail); // ["Г", "Д", "Е"]

// Последние 2 элемента — отрицательный индекс
let last2 = letters.slice(-2);
console.log(last2); // ["Д", "Е"]

// Полная копия массива (часто используется!)
let copy = letters.slice();
console.log(copy); // ["А", "Б", "В", "Г", "Д", "Е"]
splice vs slice — как не запутаться?
  • splice — изменяет оригинальный массив (splices = резать/соединять)
  • slice — возвращает новый массив, оригинал не трогает (slice = ломтик)

🔍 indexOf() и includes() — поиск в массиве

Часто нужно проверить — есть ли такой элемент в массиве? Или найти его позицию?

let fruits = ["яблоко", "банан", "апельсин", "банан"];

// indexOf — возвращает ИНДЕКС первого вхождения (или -1 если не найдено)
console.log(fruits.indexOf("банан"));    // 1 — первый "банан" на позиции 1
console.log(fruits.indexOf("манго"));   // -1 — не найдено
console.log(fruits.indexOf("банан", 2)); // 3 — ищем начиная с индекса 2

// includes — возвращает true/false
console.log(fruits.includes("апельсин")); // true
console.log(fruits.includes("манго"));    // false

// Частый паттерн: проверить перед удалением
let index = fruits.indexOf("банан");
if (index !== -1) {
  fruits.splice(index, 1); // удаляем
  console.log(fruits); // ["яблоко", "апельсин", "банан"]
}

💡 Когда что использовать: если нужен просто ответ «есть или нет» — includes(). Если нужна позиция для дальнейших операций (например, чтобы удалить через splice) — indexOf().

🧪 Практика: система задач

Давайте напишем небольшой «менеджер задач» и применим все изученные методы:

let tasks = ["Изучить JS", "Сделать проект", "Сдать задание"];

// Добавить новую задачу в конец
tasks.push("Отдохнуть");
console.log(tasks); // [..., "Отдохнуть"]

// Добавить срочную задачу в начало
tasks.unshift("СРОЧНО: позвонить менеджеру");
console.log(tasks.length); // 5

// Задача выполнена — убрать первую из очереди
let done = tasks.shift();
console.log("Выполнена:", done); // "СРОЧНО: позвонить менеджеру"

// Получить только первые 2 задачи (не изменяя оригинал)
let priority = tasks.slice(0, 2);
console.log("Приоритет:", priority); // ["Изучить JS", "Сделать проект"]

// Заменить устаревшую задачу
let oldIndex = tasks.indexOf("Сдать задание");
if (oldIndex !== -1) {
  tasks.splice(oldIndex, 1, "Сдать задание (до пятницы)");
}

// Проверка
console.log(tasks.includes("Отдохнуть")); // true
console.log("Задач всего:", tasks.length);

✅ Итоги урока

  • push(el) — добавить в конец (возвращает длину); pop() — удалить с конца (возвращает элемент)
  • unshift(el) — добавить в начало; shift() — удалить с начала
  • push/pop быстрее unshift/shift, так как не нужно сдвигать элементы
  • splice(start, count, ...items) — изменяет массив: удаляет, вставляет, заменяет
  • slice(start, end) — возвращает новый массив (копию части), оригинал не меняет
  • indexOf(el) — возвращает индекс первого вхождения или -1
  • includes(el) — возвращает true/false — есть ли элемент

Следующий урок: объекты — ключевая структура данных в JavaScript. 🚀

Тест: методы изменения массивов

7 вопросов

Стек задач (push/pop)

Напишите функцию taskManager(), которая возвращает объект с методами add(task) — добавляет задачу в конец списка, и done() — удаляет последнюю задачу и возвращает её. Используйте push и pop.

Удаление элемента по индексу

Напишите функцию removeAtIndex(arr, index), которая удаляет элемент по указанному индексу с помощью splice и возвращает удалённый элемент. Если индекс вне диапазона — верните null.