2008-08-20 24 views
178

Je sais en javascript les objets doubles comme hash mais je n'ai pas été en mesure de trouver une fonction intégrée pour obtenir les clésComment trouver les clés d'un hachage?

var h = {a:'b',c:'d'}; 

Je veux quelque chose comme

var k = h.keys() ; // k = ['a','c']; 

Il est simple d'écrire une fonction moi-même pour itérer sur les éléments et ajouter les clés à un tableau que je reviens, mais y at-il une façon plus propre de faire cela?

Je continue à sentir que ça doit être une simple fonction intégrée que j'ai manquée mais que je ne trouve pas!

+0

I Je suis juste en train de sauter dans javascript mais ce message peut vous aider. http://dean.edwards.name/weblog/2006/07/enum/ –

+0

Copie possible de [Obtenir le tableau des clés de l'objet] (http://stackoverflow.com/questions/8763125/get-array-of-objects- keys) – blo0p3r

+1

Qu'en est-il de l'obtention des valeurs à partir des clés? En outre, obtenir le nombre de clés dans un hachage. –

Répondre

249

Il est fonction javascript moderne (ECMAScript 5) appelé Object.keys effectuer cette opération:

var obj = { "a" : 1, "b" : 2, "c" : 3}; 
alert(Object.keys(obj)); // will output ["a", "b", "c"] 

détails de compatibilité peuvent être trouvés here.

Sur Mozilla site il y a aussi une Snipped pour la compatibilité descendante:

if(!Object.keys) Object.keys = function(o){ 
    if (o !== Object(o)) 
     throw new TypeError('Object.keys called on non-object'); 
    var ret=[],p; 
    for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p); 
    return ret; 
} 
+0

cela n'aurait-il pas été plus naturel? 'if (! Object.prototype.keys) Object.prototype.keys = function() { if (this! == Objet (this)) throw nouveau TypeError ('Object.keys appelé sur non-object'); var ret = [], p; pour (p dans this) if (Object.prototype.hasOwnProperty.call (this, p)) ret.push (p); return ret; } var x = {a: {A: 1, B: 2, C: 3}, b: {A: 10, B: 20}}; alert (x.a.keys()); ' – ekkis

+2

Si je comprends bien,' Object.prototype.keys' rendra 'keys' disponible pour toutes les sous-classes d'Object, donc pour tous les objets. Ce que vous voulez probablement si vous essayez d'utiliser OOP. Quoi qu'il en soit, cela dépend vraiment de vos besoins. –

+1

Si vous utilisez mootools, Object.keys() devrait être disponible dans tous les navigateurs. – thepeer

13

C'est le meilleur que vous pouvez faire, pour autant que je sache ...

var keys = []; 
for (var k in h)keys.push(k); 
+2

Cela ne fonctionne pas non plus lorsque Object.prototype a été modifié. – Phil

+4

Il serait préférable de l'utiliser, et de ne pas "gâcher" Object.prototype. Il semble que tout se casse si nous ajoutons des choses à Object.prototype: c'est un idiome extrêmement commun de faire une boucle sur les clés d'un tableau/objet. –

6

Je crois que vous pouvez parcourir les propriétés de l'objet en utilisant pour /, donc vous pourriez faire quelque chose comme ça :

function getKeys(h) { 
    Array keys = new Array(); 
    for (var key in h) 
    keys.push(key); 
    return keys; 
} 
+0

Cela ne fonctionne pas, voir la réponse de Annan – Phil

79

pour le code de production nécessitant une grande compatibilité avec les navigateurs client je suggère toujours la réponse d'Ivan Nevostruev ci-dessus avec cale pour assurer Object.keys dans les anciens navigateurs. Cependant, il est possible d'obtenir la fonctionnalité exacte demandée en utilisant la nouvelle fonctionnalité defineProperty d'ECMA.

Au ECMAScript 5 - Object.defineProperty

Au ECMA5 vous pouvez utiliser Object.defineProperty() pour définir les propriétés non-dénombrables. Le current compatibility a encore beaucoup à désirer, mais cela devrait éventuellement devenir utilisable dans tous les navigateurs. (Note précisément l'incompatibilité actuelle avec IE8!)

Object.defineProperty(Object.prototype, 'keys', { 
    value: function keys() { 
    var keys = []; 
    for(var i in this) if (this.hasOwnProperty(i)) { 
     keys.push(i); 
    } 
    return keys; 
    }, 
    enumerable: false 
}); 

var o = { 
    'a': 1, 
    'b': 2 
} 

for (var k in o) { 
    console.log(k, o[k]) 
} 

console.log(o.keys()) 

# OUTPUT 
# > a 1 
# > b 2 
# > ["a", "b"] 

Cependant, depuis ECMA5 déjà ajouté Object.keys vous pourriez aussi bien utiliser:

Object.defineProperty(Object.prototype, 'keys', { 
    value: function keys() { 
    return Object.keys(this); 
    }, 
    enumerable: false 
}); 

réponse originale

Object.prototype.keys = function() 
{ 
    var keys = []; 
    for(var i in this) if (this.hasOwnProperty(i)) 
    { 
    keys.push(i); 
    } 
    return keys; 
} 

Modifier: Depuis cette réponse a été autour depuis un certain temps, je vais laisser ce qui précède intacte. Toute personne lisant ceci devrait également lire la réponse d'Ivan Nevostruev ci-dessous.

Il n'y a aucun moyen de rendre les fonctions prototypes non énumérables, ce qui les amène toujours à apparaître dans les boucles for-in qui n'utilisent pas hasOwnProperty. Je pense toujours que cette réponse serait idéale si étendre le prototype d'Object n'était pas si compliqué.

+9

'hasOwnProperty' exclut les propriétés sur les prototypes de cet objet, ce qui est utile à savoir. – ijw

+2

Réponse acceptée parce que c'est ainsi que j'ai fini par l'implémenter mais je pense que cela aurait dû être une fonction intégrée de la langue. – Pat

+5

Notez que vous devez utiliser "for (var i in this) ..." pour éviter de créer une variable globale. –

4

Je voulais utiliser la réponse ci-dessus les mieux notés

Object.prototype.keys = function() ... 

Cependant lors de l'utilisation en conjonction avec l'API Google Maps v3, Google Maps est non fonctionnel.

for (var key in h) ... 

fonctionne bien.

34

Vous pouvez utiliser Underscore.js, qui est une bibliothèque utilitaire Javascript.

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"] 
+0

Eh bien, ce n'est pas vraiment ce qui a été demandé, parce que @Pat recherche une fonction intégrée, mais c'est néanmoins une bibliothèque intéressante, et elle ne modifie pas 'Object.prototype' – fresskoma

+2

Ces jours-ci, je pense que c'est beaucoup plus utile Pour utiliser ces astucieuses petites librairies plutôt que d'écrire vos propres implémentations ... De toute façon, dans la plupart des projets du monde réel, nous utilisons de toute façon Underscore ou des bibliothèques équivalentes. Personnellement, je préfère aller avec Underscore. –

+0

'_.keys (obj) .length' pour voir s'il y a des clés. – chovy

9

utilisant jquery vous pouvez obtenir les clés comme celui-ci ...

var bobject = {primary:"red",bg:"maroon",hilite:"green"}; 
var keys = []; 
$.each(bobject, function(key,val){ keys.push(key); }); 
console.log(keys); // ["primary", "bg", "hilite"] 

Ou -

var bobject = {primary:"red",bg:"maroon",hilite:"green"}; 
$.map(bobject, function(v,k){return k;}); 

grâce à @pimlottc

+3

Si vous voulez suivre cette route, vous pouvez aussi bien utiliser 'JQuery.map': ' $ .map (h, fonction (v, k) {return k;}); ' – pimlottc

1

si vous essayez d'obtenir la éléments seulement mais pas les fonctions alors ce code peut vous aider

this.getKeys = function() { 

var keys = new Array(); 
for(var key in this) { 

    if(typeof this[key] !== 'function') { 

     keys.push(key); 
    } 
} 
return keys; 

}

cela fait partie de ma mise en œuvre du HashMap et je veux que les clés, this est l'objet hashmap qui contient les clés

38

vous pouvez utiliser Object.keys

Object.keys(h) 
+3

Ajouté dans ECMAScript 5 mais devrait travailler dans la plupart des navigateurs principaux maintenant – Pat