82 votes

En javascript, comment identifier si un objet est un Hash ou un Array ?

Le résultat de mon appel JSON peut être soit un tableau, soit un hachage. Comment puis-je faire la distinction entre les deux ?

132voto

pawel Points 7016

Les navigateurs modernes prennent en charge l'option Array.isArray(obj) méthode.

Voir MDN pour la documentation et un polyfill.

\= réponse originale de 2008 \=

vous pouvez utiliser la propriété constuctor de votre sortie :

if(output.constructor == Array){
}
else if(output.constructor == Object){
}

2 votes

Cela peut entraîner des conflits entre différentes pages, car elles ont toutes deux des instances différentes de l'attribut Array y Object fonctions constructives, qui ne seront pas comparées comme égales. Je ne sais pas exactement comment produire un exemple qui le démontre, mais je l'ai lu quelque part.

1 votes

@ripper234 Le problème se manifestera dans une multitude de cas. window l'environnement.

3 votes

+1 pour avoir mentionné Array.isArray. Consultez ce lien pour un support plus complet : kangax.github.io/compat-table/es5/#Array.isArray

34voto

Borgar Points 12493

C'est un objet :

function isObject ( obj ) {
   return obj && (typeof obj  === "object");
}

C'est un tableau :

function isArray ( obj ) { 
  return isObject(obj) && (obj instanceof Array);
}

Comme les tableaux sont des objets, vous voudrez d'abord tester si une variable est un tableau, puis si elle est un objet :

if (isArray(myObject)) {
   // do stuff for arrays
}
else if (isObject(myObject)) {
   // do stuff for objects
}

1 votes

Bonne réponse. Vous pouvez ajouter que chaque objet js peut être traité comme un hash.

0 votes

IsObject(new Date())) est vrai, mais une date n'est pas un objet/hash au sens de cette question. Bien sûr, nous pouvons simplement l'appliquer à JSON, mais le nom de la méthode est alors vraiment déroutant.

0 votes

isObject retourne vrai pour les objets et les tableaux, il est donc redondant.

9voto

insin Points 19509

Vouliez-vous dire "Objet" au lieu de "Hash" ?

>>> var a = [];
>>> var o = {};
>>> a instanceof Array
true
>>> o instanceof Array
false

6voto

neoneye Points 11545

J'ai créé une fonction pour déterminer si c'est un dictionnaire.

exports.is_dictionary = function (obj) {
    if(!obj) return false;
    if(Array.isArray(obj)) return false;
    if(obj.constructor != Object) return false;
    return true;
};

// return true
test.equal(nsa_utils.is_dictionary({}), true);
test.equal(nsa_utils.is_dictionary({abc:123, def:456}), true);

// returns false
test.equal(nsa_utils.is_dictionary([]), false);
test.equal(nsa_utils.is_dictionary([123, 456]), false);
test.equal(nsa_utils.is_dictionary(null), false);
test.equal(nsa_utils.is_dictionary(NaN), false);
test.equal(nsa_utils.is_dictionary('hello'), false);
test.equal(nsa_utils.is_dictionary(0), false);
test.equal(nsa_utils.is_dictionary(123), false);

0 votes

Merci pour cela. Cela a fonctionné pour les cas mentionnés ci-dessus. Je n'ai pas encore rencontré de cas où votre méthode échoue.

1 votes

if(Array.isArray(obj)) return false; <- N'est-ce pas redondant étant donné qu'un tableau ne passera pas le prochain contrôle de toute façon ( if(obj.constructor != Object) )?

0 votes

assert.equal(is_dictionary(new (class MyClass {})), true); échoue - l'instance de MyClass est définitivement un hash/dictionnaire.

1voto

Sergey Ilinsky Points 16803

Vérifier la propriété "constructor" de l'objet. C'est Array - c'est un objet de type tableau.

var a = {
 'b':{length:0},
 'c':\[1,2\]
}

if (a.c.constructor == Array)
   for (var i = 0; i < a.c.length; i++)
      alert(a.c\[i\]);
else
   for (var s in a.b);
      alert(a.b\[s\]);

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