Il controllo del tipo di oggetti in JS viene eseguito tramite instanceof, ie
obj instanceof Array
Questo non funzionerà se l'oggetto viene passato attraverso i confini del frame poiché ogni frame ha il proprio Arrayoggetto. È possibile aggirare questo problema controllando la proprietà [[Class]] interna dell'oggetto. Per ottenerlo, usa Object.prototype.toString()(questo è garantito per funzionare da ECMA-262):
Object.prototype.toString.call(obj) === '[object Array]'
Entrambi i metodi funzioneranno solo per array effettivi e non per oggetti simili a array come gli argumentselenchi di oggetti o nodi. Poiché tutti gli oggetti simili a un array devono avere una lengthproprietà numerica , controllerei questi in questo modo:
typeof obj !== 'undefined' && obj !== null && typeof obj.length === 'number'
Tieni presente che le stringhe superano questo controllo, il che potrebbe causare problemi poiché IE non consente l'accesso ai caratteri di una stringa in base all'indice. Pertanto, potresti voler cambiare typeof obj !== 'undefined'in typeof obj === 'object'per escludere primitive e oggetti host con tipi distinti da 'object'alltogether. Ciò consentirà comunque il passaggio degli oggetti stringa, che dovrebbero essere esclusi manualmente.
Nella maggior parte dei casi, quello che vuoi veramente sapere è se puoi iterare sull'oggetto tramite indici numerici. Pertanto, potrebbe essere una buona idea controllare se l'oggetto ha invece una proprietà denominata 0, che può essere eseguita tramite uno di questi controlli:
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
Il cast in object è necessario per funzionare correttamente per primitive tipo array (cioè stringhe).
Ecco il codice per controlli affidabili per gli array JS:
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
e oggetti simili ad array iterabili (cioè non vuoti):
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;
}
}