How to find keys of a hash?

How to find keys of a hash?

I know in javascript Objects double as hashes but i have been unable to find a built in function to get the keys
var h = {a:’b’,c:’d’};

I want something like
var k = h.keys() ; // k = [‘a’,’c’];

It is simple to write a function myself to iterate over the items and add the keys to an array that I return, but is there a standard cleaner way to do that?
I keep feeling it must be a simple built in function that I missed but I can’t find it!

Solutions/Answers:

Solution 1:

There is function in modern JavaScript (ECMAScript 5) called Object.keys performing this operation:

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

Compatibility details can be found here.

On the Mozilla site there is also a snippet for backward compatibility:

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;
}

Solution 2:

For production code requiring a large compatibility with client browsers I still suggest Ivan Nevostruev’s answer above with shim to ensure Object.keys in older browsers. However, it’s possible to get the exact functionality requested using ECMA’s new defineProperty feature.

Related:  How do I send a cross-domain POST request via JavaScript?

As of ECMAScript 5 – Object.defineProperty

As of ECMA5 you can use Object.defineProperty() to define non-enumerable properties. The current compatibility still has much to be desired, but this should eventually become usable in all browsers. (Specifically note the current incompatibility with 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"]

However, since ECMA5 already added Object.keys you might as well use:

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

Original answer

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

Edit: Since this answer has been around for a while I’ll leave the above untouched. Anyone reading this should also read Ivan Nevostruev’s answer below.

There’s no way of making prototype functions non-enumerable which leads to them always turning up in for-in loops that don’t use hasOwnProperty. I still think this answer would be ideal if extending the prototype of Object wasn’t so messy.

Related:  How to completely DISABLE any MOUSE CLICK

Solution 3:

you can use Object.keys

Object.keys(h)

Solution 4:

You could use Underscore.js, which is a Javascript utility library.

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

Solution 5:

This is the best you can do, as far as I know…

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

Solution 6:

using jQuery you can get the keys like this:

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

Or:

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

thanks to @pimlottc