2008-08-20 38 views
178

Sé que en javascript Objetos doble como hashes, pero no he sido capaz de encontrar una función integrada para conseguir las llaves¿Cómo encontrar las claves de un hash?

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

quiero algo así como

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

Es fácil de escribir una función a mí mismo para iterar sobre los elementos y agregar las claves a una matriz que devuelvo, pero ¿hay una manera más limpia estándar para hacer eso?

Sigo sintiendo que debe ser una simple función incorporada que me perdí pero no puedo encontrarlo.

+0

I Estoy entrando en javascript pero esta publicación puede ayudarte. http://dean.edwards.name/weblog/2006/07/enum/ –

+0

Posible duplicado de [Obtener matriz de claves del objeto] (http://stackoverflow.com/questions/8763125/get-array-of-objects- teclas) – blo0p3r

+1

¿Qué tal obtener los valores de las claves? Además, obtener la cantidad de claves en un hash. –

Respuesta

249

hay función en Javascript moderna (ECMAScript 5) llamó Object.keys realizar esta operación:

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

detalles de compatibilidad se pueden encontrar here.

En Mozilla site también hay un cortado con tijeras para compatibilidad con versiones anteriores:

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

¿no hubiera sido esto más natural? 'if (! Object.prototype.keys) Object.prototype.keys = function() { if (this! == Object (this)) arroja un nuevo TypeError ('Object.keys invoca a non-object'); var ret = [], p; para (p en esto) 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

Según tengo entendido,' Object.prototype.keys' pondrá 'keys' a disposición de todas las subclases de Object, por lo tanto, para todos los objetos. Lo cual probablemente quieras si estás tratando de usar OOP. De todos modos, esto realmente depende de tus requisitos. –

+1

Si usa mootools, Object.keys() debería estar disponible en todos los navegadores. – thepeer

13

Esto es lo mejor que puede hacer, por lo que yo sé ...

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

Esto tampoco funciona cuando Object.prototype ha sido alterado. – Phil

+4

Sería mejor usar esto, y no "meterse con" Object.prototype. Parece que todo se rompe si agregamos cosas a Object.prototype: es una expresión extremadamente común para recorrer las teclas de una matriz/objeto. –

6

Creo que se puede recorrer las propiedades del objeto utilizando para/en, por lo que podría hacer algo como esto :

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

Esto no funciona, ver la respuesta de Annan – Phil

79

Por el código de producción que requiere una gran compatibilidad con los navegadores cliente todavía sugieren respuesta de Ivan Nevostruev anterior con cuña para asegurar Object.keys en navegadores antiguos. Sin embargo, es posible obtener la funcionalidad exacta solicitada utilizando la nueva función defineProperty de ECMA.

A partir de ECMAScript 5 - Object.defineProperty

A partir de ECMA5 puede utilizar para definir las propiedades Object.defineProperty() no enumerables. El current compatibility todavía tiene mucho que desear, pero finalmente debería poder usarse en todos los navegadores. (Específicamente en cuenta la incompatibilidad actual con 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"] 

Sin embargo, desde ECMA5 ya se añadió Object.keys que también podría utilizar:

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

Respuesta original

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

Editar: Dado que esta respuesta ha existido por un tiempo, dejaré intacta lo de arriba. Cualquiera que lea esto también debe leer la respuesta de Ivan Nevostruev a continuación.

No hay forma de hacer que las funciones de prototipo no sean enumerables, lo que las lleva a aparecer siempre en bucles for-in que no usan hasOwnProperty. Sigo pensando que esta respuesta sería ideal si ampliar el prototipo de Object no fuera tan desordenado.

+9

'hasOwnProperty' excluye las propiedades en los prototipos de este objeto, que es útil saber. – ijw

+2

Se aceptó la respuesta porque así fue como terminé implementándola, pero creo que debería haber sido una función incorporada del lenguaje. – Pat

+5

Tenga en cuenta que debe usar "for (var i in this) ..." para evitar la creación de una variable global. –

4

que quería utilizar la respuesta más valorados por encima de

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

Sin embargo cuando se utiliza en conjunción con la versión 3 del API de Google Maps, los mapas de Google es no funcional.

for (var key in h) ... 

funciona bien.

34

Usted podría utilizar Underscore.js, que es una biblioteca de utilidades Javascript.

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

Bueno, no es realmente lo que se preguntó, porque @Pat está buscando una función incorporada, pero es una biblioteca interesante, sin embargo, y no modifica 'Object.prototype' – fresskoma

+2

En estos días, creo que es mucho más útil para usar estas ingeniosas librerías pequeñas que seguir escribiendo sus propias implementaciones ... De todos modos, en la mayoría de los proyectos del mundo real, de todos modos estamos usando bibliotecas Underscore o equivalentes. Personalmente, preferiría ir con Underscore. –

+0

'_.keys (obj) .length' para ver si hay claves. – chovy

9

usando jQuery puede obtener las claves de este tipo ...

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

O -

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

gracias a @pimlottc

+3

Si desea seguir esta ruta, también puede usar 'JQuery.map': ' $ .map (h, función (v, k) {return k;}); ' – pimlottc

1

si usted está tratando de obtener el solo elementos pero no las funciones, entonces este código puede ayudarlo

this.getKeys = function() { 

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

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

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

}

esto es parte de mi aplicación de la HashMap y sólo quiero las llaves, this es el objeto HashMap que contiene las claves

38

puede utilizar Object.keys

Object.keys(h) 
+3

Agregado en ECMAScript 5 pero debería funcionar en la mayoría de los principales navegadores por ahora – Pat

Cuestiones relacionadas