Comment vérifier si une variable est un tableau dans JavaScript? [dupliquer]

cette question a déjà une réponse ici:

je voudrais vérifier si une variable est un tableau ou une valeur unique en JavaScript.

j'ai trouvé une solution possible...

if (variable.constructor == Array)...

est-ce la meilleure façon de faire?

1519
demandé sur Andy McCluggage 2009-04-20 13:02:59

23 réponses

Il y a plusieurs façons de vérifier si une variable est un tableau ou pas. La meilleure solution est celle que vous avez choisie.

variable.constructor === Array

C'est la méthode la plus rapide sur Chrome, et probablement tous les autres navigateurs. Tous les tableaux sont des objets, donc vérifier la propriété du constructeur est un processus rapide pour les moteurs JavaScript.

si vous avez des problèmes à trouver si une propriété objects est un tableau, vous devez d'abord vérifier si la propriété est y.

variable.prop && variable.prop.constructor === Array

D'autres façons sont:

variable instanceof Array

cette méthode tourne autour de 1/3 de la vitesse comme premier exemple. C'est encore solide, ça a l'air plus propre, si vous êtes tout à propos de joli code et pas tellement sur la performance. Notez que la vérification des nombres ne fonctionne pas comme variable instanceof Number retourne toujours false . mise à Jour: instanceof va maintenant 2/3 de la vitesse!

Array.isArray(variable)

Ce dernier est, à mon avis, le plus laid, et il est l'un des plus lents. En tournant environ 1/5 de la vitesse comme premier exemple. Tableau.prototype, est en fait un tableau. vous pouvez lire plus à ce sujet ici https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

donc une autre mise à jour

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

Ce mec est le plus lent pour essayer de vérifier tableau. Cependant, il s'agit d'un guichet unique pour tous les types que vous recherchez. Cependant, puisque vous êtes à la recherche d'un tableau, utilisez juste la méthode la plus rapide ci-dessus.

J'ai aussi fait un test: http://jsperf.com/instanceof-array-vs-array-isarray/33 alors amusez-vous et vérifiez.

Note: @EscapeNetscape a créé un autre test comme jsperf.com est en bas. http://jsben.ch/#/QgYAV je voulais m'assurer que le le lien original reste pour chaque fois que jsperf revient en ligne.

1367
répondu jemiloii 2017-10-04 11:53:18

vous pouvez également utiliser:

if (value instanceof Array) {
  alert('value is Array!');
} else {
  alert('Not an array');
}

cela me semble une solution assez élégante, mais à chacun sa propre.

Edit:

à partir de ES5 il y a maintenant aussi:

Array.isArray(value);

mais cela va casser sur les navigateurs plus anciens, sauf si vous utilisez des polyfills (essentiellement... IE8 ou similaire).

985
répondu Brett Bender 2017-08-04 20:41:43

j'ai remarqué que quelqu'un a mentionné jQuery, mais je ne savais pas qu'il y avait une fonction isArray() . Il s'avère qu'il a été ajouté dans la version 1.3.

jQuery le met en œuvre comme Peter le suggère:

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

ayant déjà beaucoup fait confiance à jQuery (en particulier leurs techniques pour la compatibilité entre navigateurs), je vais soit passer à la version 1.3 et utiliser leur fonction (à condition que la mise à jour ne provoque pas trop de problèmes) ou utilisez cette méthode suggérée directement dans mon code.

Merci beaucoup pour les suggestions.

73
répondu Andy McCluggage 2012-11-15 17:12:56

il y a plusieurs solutions avec toutes leurs propres bizarreries. cette page donne un bon aperçu. Une solution possible est:

function isArray(o) {
  return Object.prototype.toString.call(o) === '[object Array]'; 
}
71
répondu Peter Smit 2015-10-11 19:31:53

dans les navigateurs modernes (et certains navigateurs anciens), vous pouvez faire

Array.isArray(obj)

( supporté par Chrome 5, Firefox 4.0, IE 9, Opera 10.5 et Safari 5)

si vous avez besoin de prendre en charge les anciennes versions de IE, vous pouvez utiliser es5-shim pour polyfill Array.isArray; ou ajouter le texte suivant

# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }
};

si vous utilisez jQuery vous pouvez utiliser jQuery.isArray(obj) ou $.isArray(obj) . Si vous utilisez vous pouvez utiliser _.isArray(obj)

Si vous n'avez pas besoin de détecter des tableaux créés dans des cadres différents, vous pouvez aussi utiliser instanceof

obj instanceof Array

Note : le mot-clé arguments qui peut être utilisé pour accéder à l'argument d'une fonction n'est pas un tableau, même si elle se comporte (habituellement) comme un:

var func = function() {
  console.log(arguments)        // [1, 2, 3]
  console.log(arguments.length) // 3
  console.log(Array.isArray(arguments)) // false !!!
  console.log(arguments.slice)  // undefined (Array.prototype methods not available)
  console.log([3,4,5].slice)    // function slice() { [native code] } 
}
func(1, 2, 3)
54
répondu Fela Winkelmolen 2016-03-10 15:08:45

C'est une vieille question mais ayant le même problème j'ai trouvé une solution très élégante que je veux partager.

L'ajout D'un prototype à Array le rend très simple

Array.prototype.isArray = true;

Maintenant si vous avez un objet que vous souhaitez tester pour voir si son un tableau tous vous avez besoin est de vérifier pour la nouvelle propriété

var box = doSomething();

if (box.isArray) {
    // do something
}

isArray n'est disponible que si son réseau

51
répondu Ibu 2011-10-24 21:12:50

Via Crockford :

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (value instanceof Array) {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

le principal défaut mentionné par Crockford est une incapacité à déterminer correctement les tableaux qui ont été créés dans un contexte différent, par exemple, window . Cette page a une version beaucoup plus sophistiquée si cela est insuffisant.

45
répondu Hank Gay 2009-04-20 09:07:33

j'aime personnellement la suggestion de Peter: https://stackoverflow.com/a/767499/414784 (pour ECMAScript 3. Pour ECMAScript 5, utilisez Array.isArray() )

les commentaires sur le post indiquent, cependant, que si toString() est changé du tout, cette façon de vérifier un tableau échouera. Si vous voulez vraiment être précis et vous assurer que toString() n'a pas été modifié, et qu'il n'y a aucun problème avec l'attribut de classe objects ( [object Array] est attribut de classe d'un objet qui est un tableau), alors je recommande de faire quelque chose comme ceci:

//see if toString returns proper class attributes of objects that are arrays
//returns -1 if it fails test
//returns true if it passes test and it's an array
//returns false if it passes test and it's not an array
function is_array(o)
{
    // make sure an array has a class attribute of [object Array]
    var check_class = Object.prototype.toString.call([]);
    if(check_class === '[object Array]')
    {
        // test passed, now check
        return Object.prototype.toString.call(o) === '[object Array]';
    }
    else
    {
        // may want to change return value to something more desirable
        return -1; 
    }
}

notez Qu'en JavaScript le guide définitif 6 Édition, 7.10, il est écrit Array.isArray() est implémenté en utilisant Object.prototype.toString.call() en ECMAScript 5. Notez également que si vous allez vous inquiéter de la modification de l'implémentation de toString() , vous devriez également vous inquiéter de chaque autre changement de méthode intégrée. Pourquoi utiliser push() ? Quelqu'un peut le changer! Une telle approche est stupide. La vérification ci-dessus est une solution offerte à ceux qui s'inquiètent du changement de toString() , mais je crois que la vérification est inutile.

26
répondu Brian 2017-05-23 12:02:58

quand j'ai posté cette question la version de JQuery que j'utilisais n'incluait pas de fonction isArray . S'il l'avait eu, je l'aurais probablement juste utilisé en espérant que l'implémentation soit la meilleure manière indépendante de navigateur pour effectuer cette vérification de type particulier.

puisque JQuery offre maintenant cette fonction, je l'utiliserais toujours...

$.isArray(obj);

(à partir de la version 1.6.2) il est encore mis en œuvre en utilisant des comparaisons sur les chaînes dans le formulaire

toString.call(obj) === "[object Array]"
19
répondu Andy McCluggage 2011-08-08 14:42:10

a pensé que je voudrais ajouter une autre option pour ceux qui pourraient déjà utiliser le Underscore.la bibliothèque js dans son script. Souligner.js a une fonction isArray () (voir http://underscorejs.org/#isArray ).

_.isArray(object) 

retourne true si l'objet est un tableau.

16
répondu Benjen 2015-09-28 13:05:32

si vous avez uniquement affaire à EcmaScript 5 et au-dessus, vous pouvez utiliser la fonction Array.isArray intégrée dans

."

par exemple,

Array.isArray([])    // true
Array.isArray("foo") // false
Array.isArray({})    // false
13
répondu JaredMcAteer 2013-07-11 14:05:20

Si vous utilisez Angulaire, vous pouvez utiliser l'angulaire.fonction isArray ()

var myArray = [];
angular.isArray(myArray); // returns true

var myObj = {};
angular.isArray(myObj); //returns false

http://docs.angularjs.org/api/ng/function/angular.isArray

10
répondu joseph.l.hunsaker 2014-03-19 08:40:02

dans de Crockford JavaScript les bonnes parties , il y a une fonction pour vérifier si l'argument donné est un tableau:

var is_array = function (value) {
    return value &&
        typeof value === 'object' &&
        typeof value.length === 'number' &&
        typeof value.splice === 'function' &&
        !(value.propertyIsEnumerable('length'));
};

explique-t-il:

tout d'abord, nous demandons si la valeur est vraie. Nous rejetons ainsi les valeurs nulles et les autres valeurs erronées. Deuxièmement, nous demandons si le type de valeur est "objet". Ce sera vrai pour les objets, les tableaux, et (bizarrement) nulle. Troisièmement, nous demandons si la valeur a une propriété de longueur qui est nombre. Ce sera toujours vrai pour les tableaux, mais généralement pas pour les objets. Quatrièmement, nous nous demandons si la valeur contient une épissure méthode. Cela sera encore vrai pour tous les tableaux. Enfin, nous nous demandons si la longueur de la propriété est énumérable (longueur produite par une dans la boucle?). Ce sera faux pour tous les tableaux. C'est le test le plus fiable pour l'agilité que j'ai trouvé. Il est regrettable que ce soit si compliqué.

9
répondu Yunzhou 2013-12-03 03:44:26

j'utilisais cette ligne de code:

if (variable.push) {
   // variable is array, since AMAIK only arrays have push() method.
}
5
répondu Saeed Neamati 2013-01-06 08:01:24

la solution universelle est ci-dessous:

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

à partir de ECMAScript 5, une solution formelle est:

Array.isArray(arr)

aussi, pour les anciennes libs JavaScript, vous pouvez trouver ci-dessous la solution bien qu'elle ne soit pas assez précise:

var is_array = function (value) {
    return value &&
    typeof value === 'object' &&
    typeof value.length === 'number' &&
    typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};

les solutions sont de http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript

4
répondu PixelsTech 2015-01-11 14:17:49

du code https://github.com/miksago/Evan.js/blob/master/src/evan.js

  var isArray = Array.isArray || function(obj) {
    return !!(obj && obj.concat && obj.unshift && !obj.callee);};
3
répondu didxga 2011-07-08 15:17:29

pour ceux qui codent-golf, un test peu fiable avec le moins de caractères:

function isArray(a) {
  return a.map;
}

cette expression est couramment utilisée lorsqu'on traverse/aplatit une hiérarchie:

function golf(a) {
  return a.map?[].concat.apply([],a.map(golf)):a;
}

input: [1,2,[3,4,[5],6],[7,[8,[9]]]]
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
2
répondu Joe Frambach 2013-10-24 18:43:37

à Partir de w3schools :

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
2
répondu Jahid 2015-03-29 13:07:14

J'ai aimé la réponse de Brian:

function is_array(o){
    // make sure an array has a class attribute of [object Array]
    var check_class = Object.prototype.toString.call([]);
    if(check_class === '[object Array]')    {
        // test passed, now check
        return Object.prototype.toString.call(o) === '[object Array]';
    } else{
        // may want to change return value to something more desirable
        return -1; 
    }
}

mais vous pourriez juste faire comme ceci:

return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
1
répondu zeageorge 2013-04-20 17:17:31

j'ai créé ce petit morceau de code, qui peut retourner les types vrais.

Je ne suis pas encore sûr de la performance, mais c'est une tentative d'identifier correctement le type de.

https://github.com/valtido/better-typeOf a également blogué un peu à ce sujet ici http://www.jqui.net/jquery/better-typeof-than-the-javascript-native-typeof /

il fonctionne, similaire à l'actuel typeof.

var user = [1,2,3]
typeOf(user); //[object Array]

il pense qu'il peut avoir besoin d'un peu de réglage fin, et de prendre en compte les choses, je ne l'ai pas rencontré ou de tester correctement. d'autres améliorations sont donc les bienvenues, que ce soit sur le plan des performances ou du report incorrect de typeOf.

1
répondu Val 2014-07-28 09:32:11

je pense en utilisant myObj.constructeur==Objet et myArray.constructeur==Tableau est la meilleure façon. Son presque 20x plus rapide que d'utiliser toString(). Si vous étendez des objets avec vos propres constructeurs et voulez que ces créations soient considérées comme des "objets" aussi bien que cela ne fonctionne pas, mais autrement son chemin plus rapide. typeof est aussi rapide que la méthode du constructeur mais typeof []=='object' retourne true ce qui sera souvent indésirable. http://jsperf.com/constructor-vs-tostring

une chose à noter est que nul.constructeur lèvera une erreur donc si vous pourriez être vérifier pour les valeurs null, vous devrez d'abord faire si(testThing!= = null){}

1
répondu user1585789 2014-08-24 20:51:27

depuis le .la propriété length est spéciale pour les tableaux en javascript vous pouvez simplement dire

obj.length === +obj.length // true if obj is an array

Underlorejs et plusieurs autres bibliothèques utilisent cette astuce courte et simple.

-5
répondu TypingTurtle 2014-03-02 18:01:53

quelque chose que je viens d'inventer:

if (item.length) //This is an array else //not an array

-14
répondu trololol 2015-02-12 23:01:13