316

I have a JavaScript object like

var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}

How can I get the length and list of keys in this object?

Felix Kling
  • 756,363
  • 169
  • 1,062
  • 1,111
user160820
  • 14,296
  • 21
  • 61
  • 92
  • 1
    possible duplicate of [Get Property Names In JSON Objects](http://stackoverflow.com/questions/1876485/get-property-names-in-json-objects) – T J Oct 11 '14 at 07:17
  • 1
    @TJ I think it's not totally the same. This is an object, the duplicate is a JSON object. – GuyT Oct 13 '14 at 12:56
  • if you have underscore, then simply _.keys(your_object) – Minhaj Nov 09 '15 at 14:15
  • 1
    As things have changed since 2010, it might be better to accept the most upvoted answer as "the answer" – Jonas Wilms Jul 06 '18 at 18:58

18 Answers18

656

var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}
var keys = Object.keys(obj);
console.log('obj contains ' + keys.length + ' keys: '+  keys);

It's supported on most major browsers now.

Zanon
  • 26,047
  • 20
  • 108
  • 119
Anurag
  • 137,034
  • 36
  • 218
  • 257
  • 7
    The fact that it works in Chrome also means it works in Node.js as both are built on the V8 javascript engine. – Homme Zwaagstra May 15 '13 at 08:24
  • 9
    @fet Nowadays, yes. Two years ago, not so much. – AlbertEngelB Jun 28 '13 at 17:20
  • 4
    Note that this is different from `for(key in ob)`! `Object.keys` wont list the keys from prototypes, but `.. in obj` does. – Albert Mar 24 '14 at 12:33
  • 9
    @fet windows7 came with IE8. As great as it would be, there's no way this can be the accepted answer until people stop using IE8. – snuggles May 20 '14 at 19:04
  • 1
    Here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys you find a JavaScript method that works correctly in old browsers and doesn't overwrite the functionality in newer browsers. Also see my answer below. – Sandro Dec 01 '14 at 11:07
  • @Anurag What Object.keys(obj); does internally ? – Sunil Sharma Jan 15 '16 at 07:03
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys has a polyfill implementation for those who want to use this and support IE 8. – apokryfos Feb 22 '16 at 15:51
354

var obj = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3',
  key4: 'value4'
};
var keys = [];

for (var k in obj) keys.push(k);

console.log("total " + keys.length + " keys: " + keys);
Aryan Beezadhur
  • 3,651
  • 3
  • 16
  • 39
zed_0xff
  • 31,180
  • 7
  • 50
  • 72
  • I don't suppose Javascript is like PHP, where you can skip the first line altogether? Not that something like that is advisable to do anyway. – Bart van Heukelom Jun 18 '10 at 09:45
  • @Bart: No, the first line is necessary in JavaScript. – Daniel Vassallo Jun 18 '10 at 09:46
  • 6
    You should take a look at David Morrissey's comment below for an edge case here. Sometimes taking this approach will result in unwanted members of the prototype showing up in `keys`. –  Oct 07 '10 at 02:29
  • 2
    @pat: If you're using object literals, that'll only happen if you extend `Object.prototype`, which you should not be doing anyway. For custom constructors, though, you are right. – Sasha Chedygov Oct 23 '10 at 08:02
  • @BartvanHeukelom even back in june 2010 that caused a notice, as it means you're implicitly typing the object. Assigning `[]` to it (or `array()` back then) makes it an array, which you can then use as an array safely. – Niels Keurentjes Nov 29 '14 at 23:28
  • @Bart there's an ugly `[]=` operator for PHP identifiers but in javascript when you do `myUndefinedVar.push` you are trying to retrieve the property `push` from and object of type `'undefined'` which causes a reference error; note I haven't even typed the parens and arguments after push – Rivenfall Nov 18 '15 at 14:35
27

Underscore.js makes the transformation pretty clean:

var keys = _.map(x, function(v, k) { return k; });

Edit: I missed that you can do this too:

var keys = _.keys(x);
mikebridge
  • 3,739
  • 2
  • 36
  • 45
  • That's correct, the actual underscore source:nativeKeys = Object.keys; hasOwnProperty = ObjProto.hasOwnProperty; _.has = function(obj, key) { return hasOwnProperty.call(obj, key); }; _.keys = nativeKeys || function(obj) { if (obj !== Object(obj)) throw new TypeError('Invalid object'); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); return keys; }; – Miguel Alejandro Fuentes Lopez Dec 16 '13 at 19:04
18

If you only want the keys which are specific to that particular object and not any derived prototype properties:

function getKeys(obj) {
    var r = []
    for (var k in obj) {
        if (!obj.hasOwnProperty(k)) 
            continue
        r.push(k)
    }
    return r
}

e.g:

var keys = getKeys({'eggs': null, 'spam': true})
var length = keys.length // access the `length` property as usual for arrays
cryo
  • 13,751
  • 4
  • 31
  • 35
4

Anurags answer is basically correct. But to support Object.keys(obj) in older browsers as well you can use the code below that is copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys . It adds the Object.keys(obj) method if it's not available from the browser.

if (!Object.keys) {
 Object.keys = (function() {
 'use strict';
 var hasOwnProperty = Object.prototype.hasOwnProperty,
    hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
    dontEnums = [
      'toString',
      'toLocaleString',
      'valueOf',
      'hasOwnProperty',
      'isPrototypeOf',
      'propertyIsEnumerable',
      'constructor'
    ],
    dontEnumsLength = dontEnums.length;

return function(obj) {
  if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
    throw new TypeError('Object.keys called on non-object');
  }

  var result = [], prop, i;

  for (prop in obj) {
    if (hasOwnProperty.call(obj, prop)) {
      result.push(prop);
    }
  }

  if (hasDontEnumBug) {
    for (i = 0; i < dontEnumsLength; i++) {
      if (hasOwnProperty.call(obj, dontEnums[i])) {
        result.push(dontEnums[i]);
      }
    }
  }
  return result;
};
}());
}
Sandro
  • 1,677
  • 1
  • 19
  • 28
4
var keys = new Array();
for(var key in obj)
{
   keys[keys.length] = key;
}

var keyLength = keys.length;

to access any value from the object, you can use obj[key];

dotcoder
  • 2,748
  • 9
  • 31
  • 50
4

Use Object.keys()... it's the way to go.

Full documentation is available on the MDN site linked below:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

jshaw3
  • 321
  • 2
  • 15
4
obj = {'a':'c','b':'d'}

You can try:

[index for (index in obj)] 

this will return:

['a','b']

to get the list of keys or

[obj[index] for (index in obj)]

to get the values

Udo Held
  • 11,937
  • 11
  • 67
  • 90
Jim Nolan
  • 49
  • 1
3

Note that in coffeescript this can be accomplished in all browsers and node as

k for k of obj

and thus

(1 for _ of obj).length
Tim James
  • 1,413
  • 1
  • 14
  • 15
3

Recursive solution for browsers that support ECMAScript 5:

var getObjectKeys = function(obj) {
    var keys = Object.keys(obj);
    var length = keys.length;

    if (length !== 0) {
        for (var i = 0; i < length; i++) {
            if (typeof obj[keys[i]] === 'object') {
                keys[keys[i]] = getObjectKeys(obj[keys[i]]);
            }
        }
    }

    return keys;
};
Jordi
  • 1,058
  • 1
  • 8
  • 18
3
var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}

console.log(Object.keys(obj));
console.log(Object.keys(obj).length)
bajran
  • 1,341
  • 13
  • 22
3

If you decide to use Underscore.js you better do

var obj = {
    key1: 'value1',
    key2: 'value2',
    key3: 'value3',
    key4: 'value4'
}

var keys = [];
_.each( obj, function( val, key ) {
    keys.push(key);
});
console.log(keys.lenth, keys);
kalehmann
  • 4,449
  • 6
  • 23
  • 35
mohammad javad ahmadi
  • 1,877
  • 1
  • 9
  • 26
3

In JavaScript, an object is a standalone entity, with properties and type.

For fetching values from Object in form of array: Object.values(obj) // obj is object name that you used Result -> ["value1", "value2", "value3", "value4"]

For fetching keys from Object in form of array: Object.keys(obj) // obj is object name that you used Result -> ["key1", "key2", "key3", "key4"]

As both functions are returning array you can get the length of keys or value by using length property. For instance - Object.values(obj).length or Object.keys(obj).length

3

Modern browsers do support:

var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}
console.log(Object.keys(obj));
// we can also get values
console.log(Object.values(obj));
Apoorva Chikara
  • 1
  • 3
  • 18
  • 29
2

For a comma-delineated string listing the keys of a JSON Object, try the following:

function listKeys(jObj){
    var keyString = '';
    for(var k in jObj){
        keyString+=(','+k);
    }
    return keyString.slice(1);
}



/* listKeys({'a' : 'foo', 'b' : 'foo', 'c' : 'foo'}) -> 'a,b,c' */
Christian
  • 21
  • 2
2

Using ES6, you can use forEach to iterate over the Keys of an Object. To get all the keys you can use Object.keys which returns all the keys in an Object

Object.keys(obj).forEach(function(keyValue, index, map) { 
  console.log(keyValue); 
});

Short hand of the above snippet would be, which only takes one parameter

Object.keys(obj).forEach(function(keyValue) { 
  console.log(keyValue); 
});
Rinav
  • 2,347
  • 8
  • 32
  • 51
1
       if(props.userType){
          var data = []
          Object.keys(props.userType).map(i=>{
                data.push(props.userType[i])
          })
          setService(data)
        }
0

using slice, apply and join method.

var print = Array.prototype.slice.apply( obj );
alert('length='+print.length+' list'+print.join());