Что выведет консоль в случае удаления элемента массива с помощью оператора 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 — не одно и то же
Важно различать две ситуации:
- Свойство существует и в нём лежит
undefined - Свойства не существует вообще (пустой слот)
В обоих случаях чтение 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] | Свойства нет (дырка) | undefined | false | empty |
arr[1] = undefined | Свойство есть, значение undefined | undefined | true | undefined |
Связанные нюансы перебора
Разрежённость влияет на методы и циклы:
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), поскольку длина не является количеством существующих элементов.