Что выведет консоль в случае удаления элемента массива с помощью оператора delete?

Дан код:

const c = [1, 2, 4];
delete c["1"];

console.log(c); // Первый
console.log(c.length); // Второй

Что выведетcя в console.log-ах?

Теория по задаче

Исходный код и фактический результат

Дан код:

const c = [1, 2, 4];
delete c["1"];

console.log(c); // Первый
console.log(c.length); // Второй

После выполнения delete c["1"]:

  • в массиве появляется “пустой слот” (дырка) на позиции 1
  • значение length не пересчитывается и остаётся равным 3

Теория: массив — это объект со свойствами

В JavaScript массив является объектом, у которого:

  • индексы — это свойства с ключами-строками "0", "1", "2" и т.д.
  • length — отдельное числовое свойство, связанное с наибольшим индексом, но не равное количеству реально существующих элементов

Поэтому обращение к элементу c[1] фактически означает доступ к свойству "1" у объекта массива.

Выражения c[1] и c["1"] в данном контексте эквивалентны, так как индекс при обращении к свойству преобразуется к строке.

Что именно делает delete

Оператор delete удаляет свойство у объекта, а не “сдвигает элементы” и не “удаляет ячейку массива” в бытовом смысле.

Выполняется следующее:

  • было свойство "1" со значением 2
  • delete удаляет именно свойство "1"
  • свойство length при этом не изменяется

Именно из-за этого массив становится разрежённым (sparse array): между "0" и "2" появляется отсутствующее свойство "1".

“Пустой слот” (empty) и undefined — не одно и то же

Важно различать две ситуации:

  1. Свойство существует и в нём лежит undefined
  2. Свойства не существует вообще (пустой слот)

В обоих случаях чтение c[1] вернёт undefined, но поведение в проверках и переборах отличается.

Пример различий:

const a = [1, 2, 4];
delete a[1];

const b = [1, undefined, 4];

a[1]; // undefined
b[1]; // undefined

1 in a; // false
1 in b; // true

a.hasOwnProperty("1"); // false
b.hasOwnProperty("1"); // true

a.length; // 3
b.length; // 3

Почему console.log показывает empty, а не undefined

При выводе массива многие консоли разработчика стараются отобразить разрежённость массива явно, показывая отсутствующие элементы как empty (или “<1 empty item>”).

Это визуальное представление “дырок”, а не реальных значений.

Почему length остаётся 3

Свойство length не является “счётчиком элементов”. Оно отражает (maxIndex + 1), где (maxIndex) — наибольший индекс, который когда-либо присутствует (или присутствует сейчас) в массиве, с учётом специальных правил изменения length.

В данном массиве есть индекс "2", значит:

  • максимальный индекс (= 2)
  • length (= 2 + 1 = 3)

Удаление "1" не меняет наличие "2", поэтому length остаётся (3).

Мини-таблица: delete vs undefined

СитуацияЧто хранится в ячейке 1Возврат при чтении arr[1]1 in arrВизуально в console
delete arr[1]Свойства нет (дырка)undefinedfalseempty
arr[1] = undefinedСвойство есть, значение undefinedundefinedtrueundefined

Связанные нюансы перебора

Разрежённость влияет на методы и циклы:

  • forEach, map, filter обычно пропускают пустые слоты
  • for...in перечисляет существующие свойства, поэтому пропустит отсутствующий "1"
  • обычный цикл for (let i = 0; i < arr.length; i++) пройдёт по индексам, но на дырке чтение даст undefined

Пример:

const c = [1, 2, 4];
delete c[1];

c.forEach((v, i) => console.log(i, v)); // выведет 0 1 и 2 4, индекс 1 будет пропущен

for (let i = 0; i < c.length; i++) {
  console.log(i, c[i]); // выведет 0 1, 1 undefined, 2 4
}
Создание разрежённых массивов часто усложняет логику и отладку, поэтому для “удаления элемента” в прикладных задачах обычно применяются splice, filter или построение нового массива, а не delete.

Что было бы, если нужна именно “удаление элемента”

Если требуется убрать элемент и сдвинуть хвост влево (и уменьшить длину), применяется splice:

const c = [1, 2, 4];
c.splice(1, 1);

console.log(c); // [1, 4]
console.log(c.length); // 2

Если требуется удалить по условию без изменения исходного массива, часто создаётся новый массив:

const c = [1, 2, 4];
const d = c.filter((x, i) => i !== 1);

console.log(d); // [1, 4]

Итого: delete c["1"] удаляет свойство "1" у массива, поэтому в выводе массива появляется пустой слот [1, empty, 4], а c.length остаётся равным (3), поскольку длина не является количеством существующих элементов.