Skip to main content

Перевірка значення на масив

Щоб перевірити, що значення є масивом, використовують Array.isArray(value): це сучасний і найнадійніший спосіб, що працює навіть з масивами з інших контекстів виконання. Решта прийомів (instanceof, Object.prototype.toString.call(), typeof) або мають обмеження, або не розрізняють масив і звичайний об'єкт.

Теорія

TL;DR

  • Array.isArray(value), це рекомендований спосіб, працює скрізь і між контекстами.
  • value instanceof Array працює, але залежить від контексту: у масиву з iframe інший Array.prototype.
  • Object.prototype.toString.call(value) повертає "[object Array]", універсально, але громіздко.
  • typeof value для масиву завжди дає "object", тому для перевірки не годиться.
  • Масив, це об'єкт, тому будь-яка перевірка «це об'єкт?» пропустить і {}, і null.

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

javascript
const value = [1, 2, 3]; console.log(Array.isArray(value)); // true console.log(value instanceof Array); // true console.log(Object.prototype.toString.call(value)); // "[object Array]" console.log(typeof value); // "object"

Три перші перевірки відповідають на питання, четверта, ні.

Array.isArray, сучасний і надійний спосіб

javascript
Array.isArray([1, 2, 3]); // true Array.isArray('text'); // false Array.isArray({}); // false

Чому саме він:

  • Працює в усіх сучасних браузерах і в Node.js.
  • Правильно визначає масиви навіть з інших контекстів, наприклад з iframe, з Web Worker або з окремого контексту Node.js.
  • Не залежить від прототипу: метод перевіряє внутрішній слот значення, а не ланцюжок __proto__.
  • Це рекомендований спосіб перевірки.

instanceof Array, старий, але робочий

javascript
[1, 2, 3] instanceof Array; // true 'abc' instanceof Array; // false

Проте є застереження:

  • Якщо масив створено в іншому вікні або фреймі, результат може бути хибним, бо кожен контекст має власний конструктор Array і власний Array.prototype.
javascript
// Приклад проблеми: const foreignArray = new window.frames[0].Array(1, 2, 3); console.log(foreignArray instanceof Array); // false console.log(Array.isArray(foreignArray)); // true

Ще одна дрібниця: instanceof можна обдурити через Symbol.hasInstance або підміну прототипу, тоді як Array.isArray() такій підміні не піддається.

Перевірка через Object.prototype.toString.call()

Цей спосіб універсальний для будь-яких типів, тому його часто використовують у бібліотеках.

javascript
Object.prototype.toString.call([]); // "[object Array]" Object.prototype.toString.call({}); // "[object Object]" Object.prototype.toString.call('hi'); // "[object String]"

Він теж не залежить від контексту виконання, але повертає рядок, який треба порівнювати вручну, тому код виходить довшим за Array.isArray().

Чому typeof не підходить

javascript
typeof []; // "object"

typeof не годиться, тому що масив, це об'єкт, і результат завжди буде "object". Той самий рядок повернуть {}, null, new Date() і new Map(), тож жодної корисної інформації про масив ця перевірка не дає.

Порівняння методів

МетодПовертає для масивуНадійністьКоментар
Array.isArray(value)trueНайвищаНайкращий варіант
value instanceof ArraytrueСередняЗалежить від контексту виконання
Object.prototype.toString.call(value)"[object Array]"ВисокаУніверсальний, але громіздкий
typeof value"object"НульоваНе розрізняє масиви та інші об'єкти

Висновок: завжди використовуйте Array.isArray(value), це найточніший і найкоротший спосіб.

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

  • Перевіряти масив через typeof value === 'object'. Умова істинна також для {}, null, Date і Map.
  • Забувати про null. typeof null теж "object", тому будь-яка перевірка «об'єкт» має окремо відсіювати null.
  • Покладатися на instanceof у коді з iframe, Worker чи кількома контекстами. Там на справжньому масиві ви отримаєте false.
  • Вважати array-like масивом. arguments, NodeList і об'єкт із полем length не є масивами: Array.isArray() поверне false. Щоб отримати справжній масив, використовуйте Array.from(value) або [...value].
  • Перевіряти через value.constructor === Array. Властивість constructor легко перезаписати, до того ж на null і undefined такий код кине помилку.

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

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

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