Suggest an editImprove this articleRefine the answer for “The delete operator on an array”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`delete arr[0]` removes the value at index 0, but it does not shift the remaining elements and does not change `length`: an empty item (a hole) is left in place of the deleted element.** An array is just an object with numeric keys, so `delete` simply removes the property `0` while the array length stays the same. The result is a hole: `0 in arr` returns `false`, methods such as `forEach`, `map` and `filter` skip that position, and a direct read of `arr[0]` gives `undefined`. To remove an element and shift the rest, use `splice()`. ```javascript const arr = [10, 20, 30]; delete arr[0]; console.log(arr); // [ <1 empty item>, 20, 30 ] console.log(arr.length); // 3 ``` **Key point:** `delete` on an array removes a property, not an element: the length stays the same and a hole appears, so for arrays use `splice()` instead.Shown above the full answer for quick recall.Answer (EN)Image**`delete arr[0]` removes the value at index 0, but it does not shift the remaining elements and does not change `length`: an empty item (a hole) is left in place of the deleted element.** Formally the array does not delete an element, it deletes the property with the key `0`, which makes the array structure ragged. ## Theory ### TL;DR - The element at index `0` **disappears**, but its slot stays **empty**. - `length` **does not change**: it was `3`, it stays `3`. - The remaining elements are **not shifted** to the left. - A hole appears in the array, a so called empty slot: `0 in arr` returns `false`. - Iteration methods (`forEach`, `map`, `filter`) **skip** empty slots, while a direct read of `arr[0]` gives `undefined`. - To really remove an element, with a shift, use `splice()`. ### Quick example ```javascript const arr = [10, 20, 30]; delete arr[0]; console.log(arr); // [ <1 empty item>, 20, 30 ] console.log(arr.length); // 3 ``` The value `10` is gone, yet the array still has a length of `3`. ### What happens under the hood - `delete` is an operator for **objects**: it removes a property. An array in JavaScript is also an object, just one with numeric keys `0`, `1`, `2` and a special `length` property. - So `delete arr[0]` literally means "delete the property named `0`". - The operator does **not shift** the other elements: the keys `1` and `2` stay where they are. - The operator does **not touch** `length`: the length is a separate property and is not recalculated automatically. The result is a hole in the array, a so called empty slot (a sparse array). ### Demonstrating the hole ```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, the element really is not there ``` Note the difference between an empty slot and the value `undefined`: ```javascript const holes = [1, , 3]; // an empty slot const undef = [1, undefined, 3]; // a real undefined value console.log(1 in holes); // false console.log(1 in undef); // true ``` Both arrays return `undefined` at index `1`, but only in the second case does the property actually exist. ### Why this is not recommended Empty cells behave oddly and easily break the logic of your code. - `forEach`, `map`, `filter`, `reduce`, `some`, `every` and `Object.keys` **skip** such positions: ```javascript const arr = [1, 2, 3]; delete arr[1]; arr.forEach(el => console.log(el)); // logs only 1 and 3 ``` - But a direct read (`arr[1]`) gives you `undefined`, so a check against `undefined` cannot tell a hole from a real value. - Some of the newer methods do the opposite and treat a slot as `undefined`: `Array.from(arr)`, the spread `[...arr]`, `for...of`, `join()`, `includes()`. Because of that the same array behaves differently in different parts of the code. - JavaScript engines optimise dense arrays; a sparse array can push the internal representation into a slower mode. ### The correct way to remove an element Use `splice()` when you need to remove an element and shift the rest: ```javascript const arr = [10, 20, 30]; arr.splice(0, 1); console.log(arr); // [20, 30] console.log(arr.length); // 2 ``` If mutating the array is not allowed, build a new copy without the unwanted element: ```javascript const arr = [10, 20, 30]; const withoutFirst = arr.slice(1); // [20, 30] const withoutIndex = arr.filter((_, i) => i !== 0); // [20, 30] ``` For the first and last element there are shorter options: `shift()` and `pop()`, and both update `length` correctly. ### A short comparison | Method | What it does | Changes length | Creates a hole? | | --- | --- | --- | --- | | `delete arr[i]` | removes a property | No | Yes | | `arr.splice(i, 1)` | removes an element and shifts the rest | Yes | No | | `arr.filter(...)` | returns a new array without the element | The new array is shorter | No | > **Conclusion:** avoid `delete arr[index]` for arrays, because it leaves empty slots and makes the structure ragged. For a safe removal use `splice()`. ### Common mistakes - **Expecting `length` to shrink.** It never does: `delete` knows nothing about array semantics. - **Assuming the elements will shift.** The indexes of the remaining elements stay the same, so after `delete arr[0]` the expression `arr[1]` is still the second element. - **Confusing an empty slot with `undefined`.** Check for presence with `i in arr` or `Object.hasOwn(arr, i)`, not with `arr[i] === undefined`. - **Expecting every method to behave the same.** The older iteration methods skip holes, while spread, `for...of` and `Array.from` turn them into `undefined`. - **Using `delete` to clear an array.** To empty an array use `arr.length = 0` or `arr.splice(0)`. - **Forgetting that `delete` returns `true` almost always.** A successful return does not mean the array got shorter.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.