Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Звертання до неіснуючого індексу». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Звертання до неіснуючого індексу масиву повертає `undefined` і не кидає помилки.** Масив у JavaScript, це об'єкт, у якому індекси, це звичайні рядкові ключі, а читання відсутньої властивості об'єкта завжди дає `undefined`, а не виняток, як у деяких інших мовах. Помилка `TypeError` виникне лише тоді, коли не існує сам масив, тобто змінна дорівнює `null` або `undefined`. Щоб відрізнити відсутній елемент від значення `undefined`, використовуйте оператор `in` або `Object.hasOwn()`. ```javascript const arr = ['apple', 'banana', 'cherry']; console.log(arr[0]); // 'apple' console.log(arr[10]); // undefined, помилки немає console.log(10 in arr); // false ``` **Ключове:** неіснуючий індекс дає `undefined` без помилки; `TypeError` буде лише тоді, коли сам масив, це `null` або `undefined`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Якщо звернутися до неіснуючого індексу масиву, JavaScript поверне `undefined`, і помилки при цьому не буде.** Це не баг, а наслідок того, що масив, це об'єкт, а читання відсутньої властивості об'єкта в JavaScript завжди безпечне. ## Теорія ### TL;DR - Читання неіснуючого індексу дає `undefined`, **виняток не кидається**. - Причина: масив, це об'єкт, індекси, це рядкові ключі, а відсутня властивість повертає `undefined`. - `undefined` тут означає «значення відсутнє», а не «сталася помилка». - `TypeError` буде тільки тоді, коли не існує **сам масив**: `null` або `undefined`. - Перевірити наявність елемента можна через `index in arr` або `Object.hasOwn(arr, index)`. - Порожній слот («дірка») теж дає `undefined`, але `in` для нього поверне `false`. ### Швидкий приклад ```javascript const arr = ['apple', 'banana', 'cherry']; console.log(arr[0]); // 'apple' console.log(arr[3]); // undefined, елемента немає console.log(arr[10]); // undefined, і теж без помилки ``` Жодне з цих звертань не зупиняє виконання коду. ### Чому так відбувається У JavaScript масив, це **об'єкт**, у якому індекси, це **рядкові ключі**: ```javascript // приблизно еквівалентно const arr = { '0': 'apple', '1': 'banana', '2': 'cherry', length: 3 }; ``` Якщо звернутися до **неіснуючої властивості**, JavaScript поверне `undefined`, а не кине виняток, як це робить, наприклад, Python зі своїм `IndexError` або Java з `ArrayIndexOutOfBoundsException`. Те саме працює і для від'ємних чи дробових індексів: вони просто стають звичайними рядковими ключами, яких в об'єкті немає. ```javascript const arr = [1, 2, 3]; console.log(arr[-1]); // undefined, це ключ '-1', а не «останній елемент» console.log(arr[1.5]); // undefined console.log(arr.at(-1)); // 3, ось так беруть останній елемент ``` ### Коли помилка все ж буде `undefined` означає **«значення відсутнє»**, а не «помилка». Але якщо ви намагаєтеся звернутися до індексу масиву, якого не існує взагалі, тобто сам масив дорівнює `undefined` чи `null`, тоді буде виняток: ```javascript const arr = undefined; console.log(arr[0]); // TypeError: Cannot read properties of undefined ``` Убезпечитися допомагає опціональне звертання: ```javascript const arr = undefined; console.log(arr?.[0]); // undefined, без помилки console.log(arr?.[0] ?? 0); // 0, значення за замовчуванням ``` ### Як перевірити наявність елемента ```javascript const arr = [1, 2, 3]; console.log(2 in arr); // true, елемент з індексом 2 є console.log(5 in arr); // false, елемента немає ``` Сучасніша й безпечніша альтернатива, це `Object.hasOwn()`: ```javascript console.log(Object.hasOwn(arr, 2)); // true console.log(Object.hasOwn(arr, 5)); // false ``` Перевірка `arr[i] !== undefined` для цього не годиться: вона не відрізнить відсутній елемент від збереженого значення `undefined`. ```javascript const values = [1, undefined, 3]; console.log(values[1] !== undefined); // false, хоча елемент існує console.log(1 in values); // true ``` ### Приклад з «дірками» (порожніми слотами) ```javascript const arr = [1, , 3]; // пропущений елемент console.log(arr[1]); // undefined console.log(1 in arr); // false, комірки справді немає ``` Тобто `arr[1]` дасть `undefined`, але слот при цьому **не існує**: це порожня комірка, а не збережене значення `undefined`. ### Коротка таблиця | Ситуація | Результат | Помилка? | | --- | --- | --- | | Індекс існує | повертає значення | Ні | | Індексу немає | `undefined` | Ні | | Масив не існує (`null` або `undefined`) | `TypeError` | Так | | Порожній слот (дірка) | `undefined`, але `index in arr` дає `false` | Ні | > **Підсумок:** звертання до неіснуючого індексу масиву повертає `undefined`, але **не викликає помилку**. Така поведінка, це частина гнучкості JavaScript. ### Типові помилки - **Очікувати виняток, як в інших мовах.** Вихід за межі масиву в JavaScript мовчазний, тому помилку ви побачите значно пізніше, уже на `undefined`. - **Плутати «немає елемента» і «значення `undefined`».** Порівняння з `undefined` не дає відповіді, беріть `in` або `Object.hasOwn()`. - **Використовувати `arr[-1]` як останній елемент.** Це просто ключ `'-1'`; для останнього елемента є `arr.at(-1)` або `arr[arr.length - 1]`. - **Забувати перевірити сам масив.** Якщо дані прийшли з мережі, змінна може бути `undefined`, і тоді звертання кине `TypeError`; захистіться через `arr?.[i]`. - **Ланцюжок звертань без перевірки.** `arr[10].name` кине `TypeError`, бо `undefined` не має властивостей; пишіть `arr[10]?.name`. - **Запис у великий індекс.** `arr[100] = 1` не кине помилку, а розтягне `length` до `101` і створить дірки.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.