Перевірка на масив
Щоб перевірити, чи є значення масивом, використовують Array.isArray(value). Окрема функція потрібна тому, що масив у JavaScript, це різновид об'єкта, і typeof [] повертає 'object', тобто нічого не розрізняє.
Теорія
TL;DR
Array.isArray(value), це сучасний і надійний спосіб, стандарт ES5.- Він працює навіть тоді, коли масив створено в іншому контексті (iframe, окреме вікно).
value instanceof Arrayчитається зрозуміло, але даєfalseдля масиву з чужого контексту.Object.prototype.toString.call(value) === '[object Array]', це старий запасний спосіб.typeofдля цієї задачі не підходить: для масиву він повертає'object'.- Схожий на масив об'єкт (
{ length: 2 }) не є масивом, і жодна з перевірок не скаже інакше.
Швидкий приклад
console.log(Array.isArray([1, 2, 3])); // true
console.log(Array.isArray('hello')); // false
console.log(Array.isArray({ length: 0 })); // false
console.log(Array.isArray(new Array())); // true
console.log(Array.isArray(null)); // falseСпосіб 1: Array.isArray()
Array.isArray(value);Це стандартний метод ES5, створений спеціально для цієї перевірки. Він повертає true, якщо значення є масивом, і false в усіх інших випадках.
Array.isArray([1, 2, 3]); // true
Array.isArray([]); // true
Array.isArray('text'); // false
Array.isArray({ 0: 'a', 1: 'b', length: 2 }); // false
Array.isArray(null); // falseМетод працює коректно навіть між різними контекстами виконання (iframe, окреме вікно тощо), бо перевіряє внутрішній слот значення, а не його прототип. Саме це робить його єдиним повністю надійним способом.
Спосіб 2: instanceof Array
value instanceof Array;Приклад:
console.log([1, 2, 3] instanceof Array); // true
console.log({} instanceof Array); // falseНедолік: якщо масив створено в іншому вікні або в iframe, перевірка дасть false, бо в того масиву інший конструктор Array:
// у кожного контексту свій глобальний Array
iframe.contentWindow.Array !== window.Array;instanceof іде прототипним ланцюжком, а прототипи з різних контекстів, це різні об'єкти. Додатково перевірку можна обдурити, підмінивши прототип об'єкта.
Спосіб 3: Object.prototype.toString
Object.prototype.toString.call(value) === '[object Array]';Приклад:
console.log(Object.prototype.toString.call([1, 2, 3])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"Працює коректно, зокрема й між контекстами, але виглядає громіздко, тому зараз майже завжди замінюється на Array.isArray(). Історично це був основний спосіб до появи ES5, і його досі можна зустріти в поліфілах.
Порівняння способів
| Метод | Повертає | Плюси | Мінуси |
|---|---|---|---|
Array.isArray() | true / false | Сучасний, надійний, читабельний | Немає |
instanceof Array | true / false | Зрозумілий синтаксис | Не працює між різними контекстами |
Object.prototype.toString.call() | "[object Array]" | Працює завжди | Складний запис |
Типові помилки
- Перевіряти через
typeof.typeof []дає'object', так само як і для{}таnull, тому розрізнити нічим. - Покладатися на наявність
length. У рядка і вargumentsтеж єlength, але масивами вони не є. - Використовувати
instanceofдля даних з iframe або з іншого вікна. Там інший глобальнийArray, і перевірка мовчки повернеfalse. - Плутати «схожий на масив» і «масив».
argumentsіNodeList, це array-like колекції: перебирати їх можна, але методів масиву в них немає. Перетворити їх дозволяєArray.from(). - Забувати, що
null, це теж'object'. Перевірку на масив не можна замінити перевіркоюtypeof value === 'object'.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.