Reputation: 36702
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
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
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
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
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
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
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
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
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