328

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
  • 795,719
  • 175
  • 1,089
  • 1,143
user160820
  • 14,866
  • 22
  • 67
  • 94

19 Answers19

666

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
  • 29,231
  • 20
  • 113
  • 126
Anurag
  • 140,337
  • 36
  • 221
  • 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
  • WARNING: `Object.keys(obj)` would also convert all keys to strings under the hood, so if you have integers as keys, the resulting list would be wrong e.g. ['1', '2', '3'] instead of [1, 2, 3]. – mechatroner Aug 03 '22 at 00:13
358

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
  • 4,503
  • 4
  • 21
  • 42
zed_0xff
  • 32,417
  • 7
  • 53
  • 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
  • 4,209
  • 2
  • 40
  • 50
  • 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
  • 14,219
  • 4
  • 32
  • 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,757
  • 1
  • 19
  • 29
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,828
  • 10
  • 34
  • 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
  • 331
  • 2
  • 15
4

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
  • 8,277
  • 3
  • 20
  • 35
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
  • 12,314
  • 11
  • 67
  • 93
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,513
  • 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,108
  • 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,433
  • 14
  • 23
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,821
  • 6
  • 26
  • 36
mohammad javad ahmadi
  • 2,031
  • 1
  • 10
  • 27
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

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,527
  • 8
  • 33
  • 55
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());
0

Here is solution for getting all the keys from an nested object/array.

It will recursively check for the object inside an array.

function Keys() {
  let keys = [];
  this.pushKey = function (key) {
    keys.push(key);
  };
  this.getKeys = function () {
    return keys;
  };
}

let keys = new Keys();

let arr = [
  {
    a: 1,
    b: {
      c: [{ d: 1, e: [{ f: 1 }] }],
    },
  },
  {
    g: 1,
    h: {
      i: [{ j: 1, k: [{ l: 1 }] }],
    },
  },
];

function getObject(arr) {
  for (let item of arr) {
    if (Array.isArray(item)) getObject(item);
    else getKeys(item);
  }
}

function getKeys(obj) {
  for (let key in obj) {
    if (Array.isArray(obj[key])) getObject(obj[key]);
    else if (typeof obj[key] === "object") getKeys(obj[key]);
    keys.pushKey(key);
  }
}

getObject(arr);
console.log(keys.getKeys());