delete проти splice()
delete і splice() обидва можуть прибрати елемент масиву, але роблять це по-різному: delete видаляє лише властивість і залишає порожній слот, а splice() видаляє елемент, зсуває решту та зменшує length. Саме тому для масивів стандартним інструментом є splice(), а delete доречний для звичайних об'єктів.
Теорія
TL;DR
delete arr[i]видаляє властивість, а не елемент: індекси не зсуваються,lengthне змінюється.- Після
deleteу масиві лишається порожній слот, тобто масив стає розрідженим. splice(start, deleteCount)видаляє елементи по-справжньому: решта зсувається,lengthперераховується.splice()повертає масив видалених елементів,deleteповертає лишеtrueабоfalse.- Методи перебору (
map,forEach,filter) порожні слоти пропускають, що дає непередбачувану поведінку. - Правило:
splice()для масивів,deleteдля об'єктів.
Швидкий приклад
const a = [1, 2, 3];
const b = [1, 2, 3];
delete a[1];
b.splice(1, 1);
console.log(a); // [1, <1 empty item>, 3]
console.log(b); // [1, 3]
console.log(a.length); // 3
console.log(b.length); // 2Один і той самий намір «прибрати другий елемент» дає два зовсім різні масиви.
delete: видаляє значення, але не елемент масиву
const arr = [10, 20, 30];
delete arr[1];
console.log(arr); // [10, <1 empty item>, 30]
console.log(arr.length); // 3Що сталося:
deleteвидаляє властивість з об'єкта, а масив, це теж об'єкт з числовими ключами.- Місце залишається порожнім (empty slot).
- Індекси не зсуваються, довжина (
length) не змінюється.
Мінуси такого підходу:
- Масив стає «рваним», тобто з дірками.
- Методи на кшталт
.map(),.forEach(),.filter()пропускають порожні елементи. - Це часто призводить до непередбачуваної поведінки, бо
arr[1]при цьому повертаєundefined, а1 in arrповертаєfalse.
splice(): коректно видаляє елемент і зсуває решту
const arr = [10, 20, 30];
arr.splice(1, 1); // видалити 1 елемент з індексу 1
console.log(arr); // [10, 30]
console.log(arr.length); // 2Що сталося:
splice(start, deleteCount)справді видаляє елементи.- Усі елементи, що залишилися, зсуваються, індекси перераховуються.
lengthавтоматично зменшується.
Додатковий бонус: метод повертає те, що видалив, і вміє одночасно вставляти нові значення.
const arr = [10, 20, 30];
const removed = arr.splice(1, 1, 'a', 'b');
console.log(removed); // [20]
console.log(arr); // [10, 'a', 'b', 30]Таблиця порівняння
| Критерій | delete | splice() |
|---|---|---|
| Видаляє значення | Так | Так |
| Видаляє сам елемент | Ні | Так |
| Змінює довжину масиву | Ні | Так |
| Зсуває індекси | Ні | Так |
| Залишає «дірку» | Так | Ні |
| Повертає видалені елементи | Ні, лише true або false | Так, масив видалених елементів |
| Мутує вихідний масив | Так | Так |
| Рекомендується для масивів | Ні | Так |
Коли що використовувати
- Масив, потрібно видалити елемент:
splice(i, 1). - Масив, мутувати не можна:
arr.filter((_, i) => i !== index)абоarr.slice()з конкатенацією, обидва варіанти повертають новий щільний масив. - Перший або останній елемент:
shift()іpop()коротші заsplice()і теж коректно оновлюютьlength. - Звичайний об'єкт, потрібно прибрати ключ:
delete obj.key, це саме той випадок, для якого оператор і створений.
const user = { name: 'Maria', age: 25 };
delete user.age;
console.log(user); // { name: 'Maria' }Висновок:
deleteлише «затирає» комірку і залишає дірку, аsplice()реально видаляє елемент і перебудовує масив. Тому для масивів завжди берітьsplice(), аdeleteвикористовуйте тільки для звичайних об'єктів.
Типові помилки
- Видаляти елемент масиву через
delete, очікуючи, що масив стане коротшим.lengthне зміниться ніколи. - Перевіряти дірку через
arr[i] === undefined. Це не відрізнить порожній слот від реального значенняundefined; берітьi in arrабоObject.hasOwn(arr, i). - Забувати другий аргумент
splice(). Викликarr.splice(1)видалить усе від індексу1до кінця, а не один елемент. - Плутати
splice()зіslice().slice()не мутує масив і нічого не видаляє, він лише повертає копію частини. - Видаляти елементи у циклі зліва направо через
splice(). Після кожного видалення індекси зсуваються, тому йдіть з кінця масиву або використовуйтеfilter(). - Розраховувати, що
deleteповерне видалене значення. Він повертає лишеtrueабоfalse, значення потрібно зберегти заздалегідь.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.