Skip to main content

Ручна зміна length масиву

Властивість length у масиві JavaScript особлива: вона не просто показує довжину, а керує кількістю елементів. Якщо змінити її вручну, це напряму вплине на вміст масиву, тому присвоєння length треба сприймати як операцію зміни даних, а не як запис службового числа.

Теорія

TL;DR

  • length доступна і для читання, і для запису, і присвоєння змінює сам масив.
  • Менше значення обрізає масив: елементи з більшими індексами зникають безповоротно.
  • Більше значення додає порожні слоти (empty items), а не undefined.
  • Порожні слоти пропускаються методами forEach, map, filter, some, reduce.
  • arr.length = 0 очищає масив на місці, не створюючи новий.
  • Некоректне значення (-1, 1.5, 'abc') кидає RangeError: Invalid array length.

Швидкий приклад

javascript
const arr = [1, 2, 3, 4, 5]; arr.length = 3; console.log(arr); // [1, 2, 3] arr.length = 5; console.log(arr); // [1, 2, 3, <2 empty items>]

Значення, які «повернулися» після збільшення length, не відновлюються: на їх місці порожні слоти.

Зменшення length

javascript
const arr = [1, 2, 3, 4, 5]; arr.length = 3; console.log(arr); // [1, 2, 3]

Якщо зменшити length, усі елементи з більшими індексами видаляються. Це той самий результат, що й arr.splice(3), але швидший і без проміжного масиву. Дані втрачені остаточно: повернути length назад не означає повернути значення.

Збільшення length і порожні слоти

javascript
const arr = [1, 2, 3]; arr.length = 6; console.log(arr); // [1, 2, 3, <3 empty items>] console.log(arr[4]); // undefined

Якщо збільшити length, додаються порожні слоти (empty items). Вони не дорівнюють undefined, це порожні комірки, яких ніби «немає», тому, наприклад, forEach() їх пропустить.

Різницю між порожнім слотом і справжнім undefined видно так:

javascript
const sparse = [1, 2, 3]; sparse.length = 5; const dense = [1, 2, 3, undefined, undefined]; console.log(4 in sparse); // false, слота немає console.log(4 in dense); // true, там лежить undefined let visited = 0; sparse.forEach(() => visited++); console.log(visited); // 3, порожні слоти пропущено

Такий масив називають розрідженим (sparse array). Частина операцій усе ж бачить слоти як undefined: це for...of, Array.from(), spread і join(). Через цю неоднозначність розріджених масивів краще уникати, а для заповнення використовувати Array(6).fill(0).

Очищення масиву через length = 0

javascript
const arr = [10, 20, 30]; arr.length = 0; console.log(arr); // []

Це зручний спосіб очистити масив без його перестворення. Важлива відмінність від arr = []: присвоєння length = 0 змінює той самий об'єкт, тому всі інші змінні, що посилаються на цей масив, теж побачать порожній масив. Саме тому цей прийом працює і для const.

javascript
const first = [1, 2, 3]; const second = first; first.length = 0; console.log(second); // [], те саме посилання

Що важливо знати

ДіяЩо станеться
arr.length = меншеОбріже масив, зайві елементи видаляться
arr.length = більшеДодасть порожні слоти в кінець
arr.length = 0Очистить масив на місці
Читання arr.lengthПоказує кількість елементів, на одиницю більшу за максимальний індекс
arr.length = -1Кине RangeError: Invalid array length

Типові помилки

  • Вважати, що збільшення length створює undefined. Воно створює порожні слоти, і 4 in arr поверне false.
  • Розраховувати, що forEach або map пройдуть по нових комірках. Ці методи пропускають порожні слоти, тому лічильники й підсумки будуть меншими за очікувані.
  • Намагатися відновити дані, повернувши length. Після зменшення значення втрачені, зворотне збільшення дає лише порожні слоти.
  • Плутати arr.length = 0 і arr = []. Перше очищає наявний масив для всіх посилань, друге створює новий масив і залишає старий недоторканим для решти коду.
  • Присвоювати length некоректне значення. arr.length = -1 або arr.length = 1.5 кидають RangeError, а не мовчки округлюють.
  • Судити про «розмір» об'єкта за length. У звичайного об'єкта length, це просто властивість, і зміна її нічого не видаляє.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.