Comment vérifier si une variable est un tableau dans JavaScript? [dupliquer]
cette question a déjà une réponse ici:
- Vérifier si l'objet est ensemble? 40 réponses
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?
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.
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).
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.
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]';
}
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)
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
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.
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.
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]"
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.
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
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
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é.
j'utilisais cette ligne de code:
if (variable.push) {
// variable is array, since AMAIK only arrays have push() method.
}
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
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);};
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]
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([]);
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.
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){}
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.
quelque chose que je viens d'inventer:
if (item.length)
//This is an array
else
//not an array