Как проверить, является ли объект массивом в JavaScript?
Самый надёжный способ: Array.isArray()
Лучший и рекомендуемый способ проверки, является ли значение массивом в JavaScript — это использование статического метода Array.isArray(). Он возвращает true, если переданное значение является массивом, и false в противном случае.
let arr = [1, 2, 3];
let obj = {name: "John"};
let str = "hello";
let num = 42;
let func = function() {};
let nullValue = null;
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
console.log(Array.isArray(str)); // false
console.log(Array.isArray(num)); // false
console.log(Array.isArray(func)); // false
console.log(Array.isArray(nullValue)); // false
Почему Array.isArray() — лучший выбор?
- Надёжность в разных контекстах: Метод корректно работает даже если массив был создан в другом фрейме, iframe, вкладке браузера или в Web Worker. Оператор
instanceofможет дать сбой в таких ситуациях, так как он проверяет цепочку прототипов, а разные контексты имеют разные глобальные объекты. - Поддержка всеми современными средами:
Array.isArray()поддерживается во всех современных браузерах (IE9+), Node.js и других средах выполнения JavaScript. - Простота и читаемость: Код с
Array.isArray()легко понять и поддерживать.
Почему другие методы могут быть ненадёжны?
1. Оператор typeof
Как вы уже заметили, typeof не отличает массив от объекта:
console.log(typeof [1,2,3]); // "object"
console.log(typeof {}); // "object"
2. Оператор instanceof
Работает, но имеет ограничения:
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
// Проблема: не работает между разными контекстами (фреймы, iframe)
let iframe = document.createElement('iframe');
document.body.appendChild(iframe);
let iframeArray = new iframe.contentWindow.Array(1, 2, 3);
console.log(iframeArray instanceof Array); // false — сбой!
3. Проверка через Object.prototype.toString()
Раньше это был популярный "хак", который до сих пор работает:
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
console.log(isArray([1, 2, 3])); // true
console.log(isArray({})); // false
Этот метод надёжен, но менее читаем и медленнее, чем Array.isArray(). Именно его раньше использовали как полифилл для Array.isArray() в старых браузерах.
Полифилл для старых браузеров
Если вам нужно поддерживать очень старые браузеры (IE8 и ниже), можно использовать такой полифилл:
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
Итоговая рекомендация
Всегда используйте Array.isArray() для проверки, является ли значение массивом. Это современный, надёжный и производительный способ. Для старых браузеров добавьте полифилл сверху.
Проверка через Object.prototype.toString.call()
Хотя Array.isArray() — это современный стандарт, метод Object.prototype.toString.call() остаётся полезной альтернативой, особенно если вы работаете в окружении, где Array.isArray может быть не определён (например, очень старые версии JavaScript-движков).
Этот метод работает следующим образом: он вызывает внутренний метод [[Class]] объекта, который возвращает строку вида [object Type]. Для массивов это всегда [object Array].
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
// Примеры использования
console.log(isArray([1, 2])); // true
console.log(isArray({a: 1})); // false
console.log(isArray("string")); // false
console.log(isArray(null)); // false
console.log(isArray(undefined)); // false
Преимущества этого подхода
- Надёжность: Работает корректно во всех контекстах (фреймы, iframe, разные окна), так как проверяет внутренний тип объекта, а не цепочку прототипов.
- Универсальность: Этот метод можно использовать для проверки любых встроенных типов:
[object Object],[object Date],[object RegExp]и т.д.
Недостатки
- Меньшая производительность: Выполнение
Object.prototype.toString.call()немного медленнее, чем вызовArray.isArray(), хотя в большинстве приложений эта разница незначительна. - Менее читаемый код: Синтаксис более громоздкий по сравнению с простым
Array.isArray().
Используйте этот метод, если вам нужно поддерживать экстремально старые окружения или если вы пишете универсальную утилиту для проверки типов, которая должна работать с разными видами объектов.