Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Оператор delete на масиві». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`delete arr[0]` прибирає значення з нульової позиції, але не зсуває решту елементів і не змінює `length`: на місці видаленого елемента лишається порожній слот (empty item).** Масив, це звичайний об'єкт з числовими ключами, тому `delete` просто видаляє властивість `0`, а довжина масиву залишається тією самою. У результаті з'являється «дірка»: `0 in arr` поверне `false`, методи `forEach`, `map` та `filter` цю позицію пропустять, а пряме звертання `arr[0]` дасть `undefined`. Щоб видалити елемент і зсунути решту, потрібен `splice()`. ```javascript const arr = [10, 20, 30]; delete arr[0]; console.log(arr); // [ <1 empty item>, 20, 30 ] console.log(arr.length); // 3 ``` **Ключове:** `delete` на масиві видаляє властивість, а не елемент: довжина не змінюється, натомість утворюється порожній слот, тому для масивів використовуйте `splice()`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`delete arr[0]` прибирає значення з нульової позиції, але не зсуває решту елементів і не змінює `length`: на місці видаленого елемента лишається порожній слот (empty item).** Формально масив видаляє не елемент, а властивість з ключем `0`, тому структура масиву стає «рваною». ## Теорія ### TL;DR - Елемент з індексом `0` **зникає**, але його місце залишається **порожнім (empty)**. - `length` **не змінюється**: був `3`, залишиться `3`. - Решта елементів **не зсувається** вліво. - У масиві з'являється «дірка», тобто *порожній слот*: `0 in arr` поверне `false`. - Методи перебору (`forEach`, `map`, `filter`) порожні слоти **пропускають**, а пряме звертання `arr[0]` дає `undefined`. - Щоб видалити елемент по-справжньому, зі зсувом, потрібен `splice()`. ### Швидкий приклад ```javascript const arr = [10, 20, 30]; delete arr[0]; console.log(arr); // [ <1 empty item>, 20, 30 ] console.log(arr.length); // 3 ``` Значення `10` зникло, але масив і далі має довжину `3`. ### Що відбувається «під капотом» - `delete`, це оператор для **об'єктів**: він видаляє властивість. Масив у JavaScript, це теж об'єкт, просто з числовими ключами `0`, `1`, `2` і спеціальною властивістю `length`. - Тому `delete arr[0]` означає буквально «видали властивість з ім'ям `0`». - Оператор **не зсуває** інші елементи: ключі `1` і `2` залишаються на своїх місцях. - Оператор **не чіпає** `length`: довжина масиву задається окремою властивістю і автоматично не перераховується. У підсумку в масиві утворюється «дірка», так званий порожній слот (sparse array). ### Демонстрація «дірки» ```javascript const arr = [1, 2, 3]; delete arr[1]; console.log(arr); // [1, <1 empty item>, 3] console.log(arr.length); // 3 console.log(1 in arr); // false, елемента справді немає ``` Зверніть увагу на різницю між порожнім слотом і значенням `undefined`: ```javascript const holes = [1, , 3]; // порожній слот const undef = [1, undefined, 3]; // справжнє значення undefined console.log(1 in holes); // false console.log(1 in undef); // true ``` Обидва масиви на позиції `1` повертають `undefined`, але лише в другому випадку властивість реально існує. ### Чому так робити не варто Порожні комірки поводяться незвично і легко ламають логіку коду. - `forEach`, `map`, `filter`, `reduce`, `some`, `every` та `Object.keys` такі позиції **пропускають**: ```javascript const arr = [1, 2, 3]; delete arr[1]; arr.forEach(el => console.log(el)); // виведе тільки 1 і 3 ``` - Але при прямому звертанні (`arr[1]`) ви отримаєте `undefined`, тому перевірка на `undefined` не відрізнить порожній слот від реального значення. - Частина сучасніших методів, навпаки, трактує слот як `undefined`: `Array.from(arr)`, spread `[...arr]`, `for...of`, `join()`, `includes()`. Через це той самий масив у різних місцях коду поводиться по-різному. - Двигуни JavaScript оптимізують щільні масиви; розріджений масив може перевести внутрішнє представлення у повільніший режим. ### Правильний спосіб видалити елемент Використовуйте `splice()`, якщо потрібно видалити елемент і зсунути решту: ```javascript const arr = [10, 20, 30]; arr.splice(0, 1); console.log(arr); // [20, 30] console.log(arr.length); // 2 ``` Якщо масив мутувати не можна, зробіть нову копію без зайвого елемента: ```javascript const arr = [10, 20, 30]; const withoutFirst = arr.slice(1); // [20, 30] const withoutIndex = arr.filter((_, i) => i !== 0); // [20, 30] ``` Для першого й останнього елемента є коротші варіанти: `shift()` і `pop()`, і обидва коректно оновлюють `length`. ### Коротке порівняння | Метод | Що робить | Змінює length | Створює «дірку»? | | --- | --- | --- | --- | | `delete arr[i]` | видаляє властивість | Ні | Так | | `arr.splice(i, 1)` | видаляє елемент і зсуває решту | Так | Ні | | `arr.filter(...)` | повертає новий масив без елемента | Новий масив коротший | Ні | > **Висновок:** `delete arr[index]` для масивів краще не використовувати, бо він залишає порожні слоти і робить структуру «рваною». Для безпечного видалення беріть `splice()`. ### Типові помилки - **Очікувати, що `length` зменшиться.** Він не зменшується ніколи: `delete` не знає про семантику масиву. - **Думати, що елементи зсунуться.** Індекси решти елементів залишаються тими самими, тому `arr[1]` після `delete arr[0]` і далі дорівнює другому елементу. - **Плутати порожній слот з `undefined`.** Перевіряйте наявність через `i in arr` або `Object.hasOwn(arr, i)`, а не через `arr[i] === undefined`. - **Розраховувати на однакову поведінку всіх методів.** Старі методи перебору дірки пропускають, а spread, `for...of` і `Array.from` перетворюють їх на `undefined`. - **Використовувати `delete` для очищення масиву.** Щоб спорожнити масив, є `arr.length = 0` або `arr.splice(0)`. - **Забувати, що `delete` повертає `true` майже завжди.** Успішне повернення не означає, що масив став коротшим.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.