Проверка типов объектов в 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;
}
}