106 votes

Comment détecter si une variable est un tableau

Quel est le meilleur standard de facto de la croix-navigateur méthode pour déterminer si une variable en JavaScript est un tableau ou pas?

La recherche sur le web il y a un certain nombre de suggestions, quelque chose de bon et tout à fait quelques pas valide.

Par exemple, ce qui suit est une approche de base:

function isArray(obj) {
    return (obj && obj.length);
}

Notez, cependant, qu'advient-il si le tableau est vide, ou obj en fait n'est pas un tableau, mais met en œuvre une longueur de propriété, etc.

Donc, de mise en œuvre qui est le meilleur en termes de travail, d'être cross-browser et continue d'accomplir de manière efficace?

167voto

Christoph Points 64389

La vérification du Type des objets dans le JS est fait via instanceof, c'est à dire

obj instanceof Array

Cela ne fonctionnera pas si l'objet est passé au-delà des limites du cadre, car chaque image a sa propre Array objet. Vous pouvez contourner ce problème en la vérification de la [[Catégorie]] propriété de l'objet. Pour l'obtenir, utiliser Object.prototype.toString() (ce qui est garanti par l'ECMA-262):

Object.prototype.toString.call(obj) === '[object Array]'

Les deux méthodes ne fonctionne que pour les réels tableaux et pas de tableau-comme des objets, comme la arguments objet de nœud ou de listes. Comme tous les tableau comme des objets doit être numérique length de la propriété, je voudrais vérifier pour ces comme ceci:

typeof obj !== 'undefined' && obj !== null && typeof obj.length === 'number'

Veuillez noter que les chaînes vont passer cette case, ce qui pourrait conduire à des problèmes que IE ne permettent pas l'accès à une chaîne de caractères en indice. Par conséquent, vous souhaiterez peut-être modifier typeof obj !== 'undefined' de typeof obj === 'object' d'exclure les primitives et les objets hôte avec des types distincts 'object' ensemble. Cela va laisser des objets string pass, qui devraient être exclus manuellement.

Dans la plupart des cas, ce que vous voulez savoir si vous pouvez effectuer une itération sur l'objet par des indices numériques. Par conséquent, il pourrait être une bonne idée de vérifier si l'objet possède une propriété nommée 0 au lieu de cela, ce qui peut être fait par l'un de ces contrôles:

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

Le casting de l'objet est nécessaire de travailler correctement pour tableau-comme les primitives (c'est à dire des chaînes de caractères).

Voici le code pour des contrôles stricts pour JS tableaux:

function isArray(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
}

et itératif (c'est à dire non-vide) tableau des objets similaires à:

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;
    }
}

46voto

Andy E Points 132925

L'arrivée d'ECMAScript 5ème Édition nous donne la plus sûre méthode pour tester si une variable est un tableau, Tableau.isArray():

Array.isArray([]); // true

Alors que l'on a accepté la réponse ici sera de travailler dans les cadres et windows pour la plupart des navigateurs, il n'est pas pour Internet Explorer 7 et plus faible, car Object.prototype.toString appelé sur un tableau à partir d'une autre fenêtre sera de retour [object Object], pas [object Array]. IE 9 semble avoir régressé à ce comportement (voir mise à jour de correctif ci-dessous).

Je n'entrerai pas dans tous les tenants et aboutissants des parties de la solution, si vous êtes intéressé, vous pouvez lire cet article de blog. Toutefois, si vous souhaitez une solution qui fonctionne sur tous les navigateurs, vous pouvez utiliser:

(function () {
    var toString = Object.prototype.toString,
        strArray = Array.toString(),
        jscript  = /*@cc_on @_jscript_version @*/ +0;

    // jscript will be 0 for browsers other than IE
    if (!jscript) {
        Array.isArray = Array.isArray || function (obj) {
            return toString.call(obj) == "[object Array]";
        }
    }
    else {
        Array.isArray = function (obj) {
            return "constructor" in obj && String(obj.constructor) == strArray;
        }
    }
})();

Il n'est pas totalement incassable, mais il ne serait brisé par quelqu'un qui essaie de casser. Il travaille autour des problèmes dans IE7 et inférieur et IE9. Le bug existe toujours dans IE 10 PP2, mais il pourrait être fixé avant la libération.

PS, si vous êtes incertain au sujet de la solution, alors je vous recommande de le tester à votre contenu de coeurs et/ou de lire le post de blog. Il y a d'autres solutions possibles-y si vous êtes mal à l'aise à l'aide de la compilation conditionnelle.

8voto

Nosredna Points 33670

Crockford a deux réponses à la page 106 du "Les Bonnes Pièces." Le premier vérifie le constructeur, mais vous donnera des faux négatifs dans différents cadres ou des fenêtres. Voici la deuxième:

if (my_value && typeof my_value === 'object' &&
        typeof my_value.length === 'number' &&
        !(my_value.propertyIsEnumerable('length')) {
    // my_value is truly an array!
}

Crockford souligne que cette version permettra d'identifier l' arguments tableau comme un tableau, même si elle n'a pas une des méthodes de tableau.

Sa discussion intéressante sur le problème commence à la page 105.

Il est en outre intéressant de discussion (post-Bonne Pièces) ici qui comprend cette proposition:

var isArray = function (o) {
    return (o instanceof Array) ||
        (Object.prototype.toString.apply(o) === '[object Array]');
};

Toute la discussion me fait jamais l'envie de savoir si oui ou non quelque chose est un tableau.

2voto

Mario Menger Points 4032

jQuery met en œuvre un isArray fonction, ce qui suggère que la meilleure façon de le faire est

function isArray( obj ) {
	return toString.call(obj) === "[object Array]";
}

(extrait de jQuery v1.3.2 - légèrement ajustée pour donner un sens hors contexte)

0voto

Otto Allmendinger Points 11853

Si vous voulez de la croix-navigateur, vous voulez jQuery.isArray.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X