Проверка типов объектов в JS осуществляется через instanceof
, т.е.
obj instanceof Array
Это не будет работать, если объект передается через границы кадра, так как каждый кадр имеет свой собственный объект Array
. Вы можете обойти это, проверив внутреннее свойство [[Class]] объекта. Чтобы получить его, используйте Object.prototype.toString()
(это гарантированно работает ECMA-262):
Object.prototype.toString.call(obj) === '[object Array]'
Оба метода будут работать только с реальными массивами, а не с объектами, похожими на массивы, такими как arguments
объект или списки узлов. Поскольку все подобные массиву объекты должны иметь числовое свойство length
, я бы проверил их следующим образом:
typeof obj !== 'undefined' && obj !== null && typeof obj.length === 'number'
Обратите внимание, что строки проходят эту проверку, что может привести к проблемам, так как IE не разрешает доступ к символам строки по индексу. Поэтому вы можете изменить typeof obj !== 'undefined'
на typeof obj === 'object'
, чтобы исключить примитивы и хост-объекты с типами, отличными от 'object'
. Это по-прежнему пропускает строковые объекты, которые должны быть исключены вручную.
В большинстве случаев вам действительно нужно знать, можете ли вы перебирать объект с помощью числовых индексов. Поэтому было бы неплохо проверить, есть ли у объекта свойство с именем 0
, что можно сделать с помощью одной из следующих проверок:
typeof obj[0] !== 'undefined' // false negative for `obj[0] = undefined`
obj.hasOwnProperty('0') // exclude array-likes with inherited entries
'0' in Object(obj) // include array-likes with inherited entries
Приведение к объекту необходимо для правильной работы для массивоподобных примитивов (т. Е. Строк).
Вот код для надежных проверок массивов JS:
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
и повторяемые (то есть непустые) объекты, похожие на массивы:
function isNonEmptyArrayLike(obj) {
try { // don't bother with `typeof` - just access `length` and `catch`
return obj.length > 0 && '0' in Object(obj);
}
catch(e) {
return false;
}
}