Pat
Pat

Reputation: 36702

How can I find the keys of an object?

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!

Upvotes: 204

Views: 213260

Answers (10)

Mouzam Ali
Mouzam Ali

Reputation: 47

In Javascript we can use

Object.keys(h)

Upvotes: 2

AnnanFay
AnnanFay

Reputation: 9739

For production code requiring a large compatibility with client browsers I still suggest Ivan Nevostruev's answer 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.

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.

Upvotes: 82

Matthew Darwin
Matthew Darwin

Reputation: 161

I wanted to use AnnanFay's answer:

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

However, when using it in conjunction with the Google Maps API v3, Google Maps is non-functional.

However,

for (var key in h) ...

works well.

Upvotes: 4

timotti
timotti

Reputation: 339

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

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

Upvotes: 33

chim
chim

Reputation: 8573

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.

Upvotes: 8

zeacuss
zeacuss

Reputation: 2623

If you are trying to get the elements only, but not the functions then this code can help you:

this.getKeys = function() {

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

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

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

This is part of my implementation of the HashMap and I only want the keys. this is the hashmap object that contains the keys.

Upvotes: 1

Leticia Santos
Leticia Santos

Reputation: 559

You can use Object.keys:

Object.keys(h)

Upvotes: 46

Ivan Nevostruev
Ivan Nevostruev

Reputation: 28713

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

Upvotes: 289

palmsey
palmsey

Reputation: 5832

I believe you can loop through the properties of the object using for/in, so you could do something like this:

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

Upvotes: 6

danb
danb

Reputation: 10379

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

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

Upvotes: 14

Related Questions