¿Cómo encontrar las claves de un hash?

Sé que en javascript los objetos se duplican como hashes, pero no he podido encontrar una función integrada para obtener las claves.

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

Quiero algo como

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

Es sencillo escribir una función yo mismo para iterar sobre los elementos y añadir las claves a un array que devuelvo, pero ¿hay una forma estándar más limpia de hacerlo?

Tengo la sensación de que debe ser una simple función incorporada que me he perdido, pero no puedo encontrarla.

Para código de producción que requiera una gran compatibilidad con los navegadores cliente, sigo sugiriendo la respuesta de Ivan Nevostruev's arriba con shim para asegurar Object.keys en navegadores antiguos. Sin embargo, es posible obtener la funcionalidad exacta solicitada utilizando la nueva función defineProperty de ECMA's.

A partir de ECMAScript 5 - Object.defineProperty.

A partir de ECMA5 se puede utilizar Object.defineProperty() para definir propiedades no enumerables. La compatibilidad actual todavía tiene mucho que desear, pero con el tiempo debería poder usarse en todos los navegadores. (¡Nótese específicamente 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, puesto que ECMA5 ya ha añadido Object.keys también se 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;
}

Edit: Dado que esta respuesta ha sido de alrededor de un tiempo I'll dejar lo anterior sin tocar. Cualquiera que lea esto también debe leer Ivan Nevostruev'respuesta de abajo.

No hay forma de hacer que las funciones prototipo no sean enumerables, lo que hace que siempre aparezcan en bucles for-in que no utilizan hasOwnProperty. Sigo pensando que esta respuesta sería ideal si extender el prototipo de Object no fuera tan complicado.

Comentarios (8)

Esto es lo mejor que puedes hacer, que yo sepa...

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

Creo que puedes hacer un bucle a través de las propiedades del objeto usando for/in, así que podrías hacer algo como esto:

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