39

When I run following code

var obj = { 0: 'a', 1: 'b', 2: 'c' };
typeof Object.keys(obj)[0] //returns string

In obj object i'm creating Number keys.

Any reason, why its string and not a number?

Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
Jagdish Idhate
  • 7,513
  • 9
  • 35
  • 51

5 Answers5

40

Keys are always of a String type. If you need numbers you will have to cast them manually:

var obj = { 0: 'a', 1: 'b', 2: 'c' };
var ids = Object.keys(obj).map(Number);

console.log(ids);
dfsq
  • 191,768
  • 25
  • 236
  • 258
23

Because Object.keys returns an array with strings

Object.keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object. The ordering of the properties is the same as that given by looping over the properties of the object manually.

You get an array of strings, because Property names are strings by definition.

Property names must be strings. This means that non-string objects cannot be used as keys in the object. Any non-string object, including a number, is typecasted into a string via the toString method.

Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • @pvg, while *`toString` is not a cast, it returns a string representation of any object. Including strings.* is true, mdn stated above. – Nina Scholz May 31 '16 at 05:52
  • 1
    Ah it makes more sense as a quote now. It's still, despite the MDN provenance, completely wrong, it's a conversion, not a cast even without the nitpicky complaint that 'typecasted' is not grammatically correct English. – pvg May 31 '16 at 06:33
4

As per the documentation Object.keys() returns string array

Object.keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object. The ordering of the properties is the same as that given by looping over the properties of the object manually.(Taken from here)

If you want to convert it to number array then use map()

var obj = {
  0: 'a',
  1: 'b',
  2: 'c'
};
console.log(typeof Object.keys(obj).map(Number)[0])
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
2

Javascript Object has no number keys! All keys are Strings. Always.

If you want to map other things to values you should use a Map.

Lux
  • 17,835
  • 5
  • 43
  • 73
0

Just some type safety to be careful of with some of the higher rated answers here (like Object.keys(obj).map(Number)) there are a lot of edge cases in .js where you may get false positive results if you map to Number). Not so much when working with object keys, but there are always oddities like why is Number([]) === 0...

In this Object.keys() example, if you have an object with mixed types that don't safely cast to a numeric type, you'll end up casting everything to NaN:

Object.keys({ "a": "1", 2: "2" }).map(Number) 
// -> [NaN, 2]
// :(

You can get a little fancy with the map method, and it will gracefully handle non-numeric keys:

Object.keys({ "a": "1", 2: "2" }).map((k) => Number.isNaN(Number(k)) ? k : Number(k)
// -> ["a", 2]
// :)
brandonscript
  • 68,675
  • 32
  • 163
  • 220