Quelle est la meilleure méthode standard pour plusieurs navigateurs pour déterminer si une variable en JavaScript est un tableau ou non?
En recherchant sur le Web, il existe un certain nombre de suggestions différentes, certaines bonnes et quelques-unes invalides.
Par exemple, voici une approche de base:
function isArray(obj) {
return (obj && obj.length);
}
Cependant, notez ce qui se passe si le tableau est vide ou si obj n'est en fait pas un tableau mais implémente une propriété length, etc.
Alors, quelle implémentation est la meilleure en termes de fonctionnement, de cross-browser et de performances efficaces?
javascript
arrays
stpe
la source
la source
Réponses:
La vérification de type des objets dans JS se fait via
instanceof
, ieCela ne fonctionnera pas si l'objet est passé à travers les limites du cadre, car chaque cadre a son propre
Array
objet. Vous pouvez contourner ce problème en vérifiant la propriété [[Class]] interne de l'objet. Pour l'obtenir, utilisezObject.prototype.toString()
(cela est garanti pour fonctionner par ECMA-262):Les deux méthodes ne fonctionneront que pour les tableaux réels et non pour les objets de type tableau comme les
arguments
listes d'objets ou de nœuds. Comme tous les objets de type tableau doivent avoir unelength
propriété numérique , je les vérifierais comme ceci:Veuillez noter que les chaînes passeront cette vérification, ce qui pourrait entraîner des problèmes car IE n'autorise pas l'accès aux caractères d'une chaîne par index. Par conséquent, vous souhaiterez peut-être passer
typeof obj !== 'undefined'
àtypeof obj === 'object'
pour exclure les primitives et les objets hôtes avec des types distincts de'object'
tous. Cela laissera toujours passer les objets string, qui devront être exclus manuellement.Dans la plupart des cas, ce que vous voulez vraiment savoir, c'est si vous pouvez parcourir l'objet via des indices numériques. Par conséquent, il peut être judicieux de vérifier si l'objet a une propriété nommée à la
0
place, ce qui peut être fait via l'une de ces vérifications:Le transtypage en objet est nécessaire pour fonctionner correctement pour les primitives de type tableau (c'est-à-dire les chaînes).
Voici le code pour des vérifications robustes pour les tableaux JS:
et objets de type tableau itérables (c'est-à-dire non vides):
la source
hasOwnProperty
méthode, donc préfixez simplement votreinstanceof
avecobj.hasOwnProperty &&
; aussi, est-ce toujours un problème avec IE7? mes tests simples via le gestionnaire de tâches suggèrent que la mémoire a été récupérée après avoir minimisé le navigateur ...L'arrivée d'ECMAScript 5e édition nous donne la méthode la plus sûre pour tester si une variable est un tableau, Array.isArray () :
Alors que la réponse acceptée ici fonctionnera dans les cadres et les fenêtres pour la plupart des navigateurs, ce n'est pas le cas pour Internet Explorer 7 et les versions antérieures , car
Object.prototype.toString
appelé sur un tableau à partir d'une fenêtre différente reviendra[object Object]
, non[object Array]
. IE 9 semble avoir régressé vers ce comportement également (voir le correctif mis à jour ci-dessous).Si vous souhaitez une solution qui fonctionne sur tous les navigateurs, vous pouvez utiliser:
Ce n'est pas entièrement incassable, mais il ne serait brisé que par quelqu'un qui essaie de le casser. Cela fonctionne autour des problèmes dans IE7 et inférieur et IE9. Le bogue existe toujours dans IE 10 PP2 , mais il pourrait être corrigé avant la publication.
PS, si vous n'êtes pas sûr de la solution, je vous recommande de la tester à votre guise et / ou de lire le billet de blog. Il existe d'autres solutions potentielles si vous ne vous sentez pas à l'aise avec la compilation conditionnelle.
la source
isArray
ne renvoie pas true à partir de tableaux créés dans d'autres modes de document? Je devrai me pencher là-dessus quand j'aurai le temps, mais je pense que la meilleure chose à faire est de signaler un bogue sur Connect afin qu'il puisse être corrigé dans IE 10.Crockford a deux réponses à la page 106 de «The Good Parts». Le premier vérifie le constructeur, mais donnera de faux négatifs sur différents cadres ou fenêtres. Voici le second:
Crockford souligne que cette version identifiera le
arguments
tableau comme un tableau, même s'il ne dispose d'aucune des méthodes de tableau.Son analyse intéressante du problème commence à la page 105.
Il y a une autre discussion intéressante (post-Good Parts) ici qui comprend cette proposition:
Toute la discussion me fait ne jamais vouloir savoir si quelque chose est ou non un tableau.
la source
jQuery implémente une fonction isArray, ce qui suggère que la meilleure façon de le faire est
(extrait de jQuery v1.3.2 - légèrement ajusté pour avoir un sens hors contexte)
la source
Object.prototype.toString()
- c'est moins susceptible de casserVoler le gourou John Resig et jquery:
la source
typeof
sont standardisées?Qu'allez-vous faire avec la valeur une fois que vous décidez qu'il s'agit d'un tableau?
Par exemple, si vous avez l'intention d'énumérer les valeurs contenues si cela ressemble à un tableau OU s'il s'agit d'un objet utilisé comme table de hachage, le code suivant obtient ce que vous voulez (ce code s'arrête lorsque la fonction de fermeture renvoie autre chose que "indéfini". Notez qu'il n'itère PAS sur les conteneurs COM ou les énumérations; cela reste un exercice pour le lecteur):
(Remarque: "o! = Null" teste à la fois null et indéfini)
Exemples d'utilisation:
la source
for..in
est mauvais [tm])for..in
itère sur les propriétés énumérables des objets; vous ne devriez pas l'utiliser avec des tableaux car: (1) c'est lent; (2) il n'est pas garanti de préserver l'ordre; (3) il inclura toute propriété définie par l'utilisateur définie dans l'objet ou l'un de ses prototypes car ES3 n'inclut aucun moyen de définir l'attribut DontEnum; il y a peut-être d'autres problèmes qui m'ont échappéSi vous faites cela dans CouchDB (SpiderMonkey), utilisez
Array.isArray(array)
comme
array.constructor === Array
ouarray instanceof Array
ne fonctionne pas. L'utilisationarray.toString() === "[object Array]"
fonctionne mais semble assez douteuse en comparaison.la source
Si vous voulez plusieurs navigateurs, vous voulez jQuery.isArray .
la source
Sur w3school, il y a un exemple qui devrait être assez standard.
Pour vérifier si une variable est un tableau, ils utilisent quelque chose de similaire à ceci
testé sur Chrome, Firefox, Safari, ie7
la source
constructor
pour la vérification de type est trop fragile; utilisez plutôt l'une des alternatives suggéréesconstructor
est une propriété DontEnum régulière de l'objet prototype; cela peut ne pas être un problème pour les types intégrés tant que personne ne fait rien de stupide, mais pour les types définis par l'utilisateur, cela peut facilement l'être; mon conseil: toujours utiliserinstanceof
, qui vérifie la chaîne de prototypes et ne repose pas sur des propriétés qui peuvent être écrasées arbitrairementL'une des versions les mieux étudiées et discutées de cette fonction se trouve sur le site PHPJS . Vous pouvez créer un lien vers des packages ou accéder directement à la fonction . Je recommande vivement le site pour des équivalents bien construits de fonctions PHP en JavaScript.
la source
Pas assez de références égales aux constructeurs. Parfois, ils ont différentes références de constructeur. J'utilise donc des représentations sous forme de chaîne.
la source
{constructor:{toString:function(){ return "function Array() { [native code] }"; }}}
Remplacer
Array.isArray(obj)
parobj.constructor==Array
échantillons:
Array('44','55').constructor==Array
retourne vrai (IE8 / Chrome)'55'.constructor==Array
return false (IE8 / Chrome)la source