Как в JavaScript проверить, является ли объект массивом?
Лучший способ: статический метод Array.isArray()
Самый надёжный и рекомендуемый способ проверить, является ли объект массивом в JavaScript — использовать статический метод Array.isArray(). Он был добавлен в стандарт ECMAScript 5.1 и поддерживается всеми современными браузерами и средами выполнения, включая Node.js, начиная с версии 0.6.0.
Вот как это работает:
const arr = [1, 2, 3];
const obj = { name: 'John' };
const str = 'hello';
const num = 42;
const func = () => {};
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
// Даже с массивами из других контекстов (например, iframe) всё работает
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeArray = iframe.contentWindow.Array;
const arrFromIframe = new iframeArray(1, 2, 3);
console.log(Array.isArray(arrFromIframe)); // true — метод надёжен!
Почему Array.isArray() — лучший выбор?
- Надёжность: Метод не подвержен проблемам с разными глобальными контекстами (iframe, фреймы, разные окна).
- Простота: Читаемый и понятный код без лишних конструкций.
- Производительность: Внутренняя реализация в движках JavaScript оптимизирована и работает быстрее, чем ручные проверки.
- Безопасность: Не может быть переопределён случайно (в отличие от проверки через instanceof, если прототип был изменён).
Почему другие способы не подходят?
1. typeof — как вы уже заметили, возвращает "object" как для массивов, так и для объектов, null и даже для некоторых других типов (например, typeof null === "object" — это известная ошибка языка).
2. instanceof Array — работает в большинстве случаев, но ломается, когда массив создан в другом контексте (например, в iframe или при передаче данных между разными окнами браузера). В таких случаях instanceof может вернуть false для настоящего массива.
3. obj.constructor === Array — аналогичная проблема: конструктор может отличаться в разных контекстах. Кроме того, свойство constructor может быть легко переопределено:
const fakeArray = { 0: 'a', 1: 'b', length: 2 };
fakeArray.constructor = Array;
console.log(fakeArray.constructor === Array); // true — хотя это не массив!
Пример использования в реальном коде
function processData(data) {
if (Array.isArray(data)) {
console.log('Это массив! Обрабатываем элементы:');
data.forEach((item, index) => {
console.log(`Элемент ${index}: ${item}`);
});
} else if (typeof data === 'object' && data !== null) {
console.log('Это объект! Обрабатываем ключи:');
for (const key in data) {
if (data.hasOwnProperty(key)) {
console.log(`${key}: ${data[key]}`);
}
}
} else {
console.log('Это примитив или null:', data);
}
}
processData([1, 2, 3]); // Это массив!
processData({a: 1, b: 2}); // Это объект!
processData('hello'); // Это примитив или null: hello
Итог: Всегда используйте Array.isArray() для проверки, является ли значение массивом. Это стандартный, надёжный и производительный метод, который работает везде.
Альтернативный подход: проверка через Object.prototype.toString
До появления Array.isArray() (и для поддержки очень старых браузеров) использовался трюк с методом toString из прототипа Object. Этот способ до сих пор работает и считается надёжным, хотя и менее удобным:
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
console.log(isArray([1, 2])); // true
console.log(isArray({})); // false
console.log(isArray('string')); // false
console.log(isArray(null)); // false
// Работает даже с массивами из iframe
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const arrFromIframe = iframe.contentWindow.Array.of(1, 2);
console.log(isArray(arrFromIframe)); // true
Как это работает?
Встроенный метод Object.prototype.toString возвращает строку вида "[object Тип]" для любого значения. Для массивов это всегда "[object Array]". Этот способ:
- Не зависит от глобального контекста (работает между iframe и окнами);
- Не может быть переопределён (если только кто-то не переопределит сам
Object.prototype.toString, что крайне маловероятно); - Работает во всех браузерах, включая Internet Explorer 6+.
Однако сегодня нет причин использовать этот метод вместо Array.isArray(), если вы не поддерживаете очень старые окружения (например, JavaScriptCore из iOS 4 или старые версии Opera). Array.isArray() короче, понятнее и быстрее в современных движках.
Мой совет: используйте Array.isArray() как основной способ, а Object.prototype.toString — только если вам по какой-то причине нужно написать полифилл для очень старых браузеров.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Оптимизация производительности Swift приложений: советы и примеры