Is there any way to use a numeric type as an object key?

123,783

Solution 1

No, this is not possible. The key will always be converted to a string. See Property Accessor docs

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.

> var foo = {}
undefined

> foo[23213] = 'swag'
'swag'

> foo
{ '23213': 'swag' }

> typeof(Object.keys(foo)[0])
'string'

Solution 2

In an object, no, but I have found Map extremely useful for this application. Here is where I have used it for numeric keys, a key-based event.

onKeydown(e) {
  const { toggleSidebar, next, previous } = this.props;

  const keyMapping = new Map([
    [ 83, toggleSidebar ],  // user presses the s button
    [ 37, next          ],  // user presses the right arrow
    [ 39, previous      ]   // user presses the left arrow
  ]);

  if (keyMapping.has(e.which)) {
    e.preventDefault();
    keyMapping.get(e.which)();
  }
}

Solution 3

Appears to be by design in ECMA-262-5:

The Property Identifier type is used to associate a property name with a Property Descriptor. Values of the Property Identifier type are pairs of the form (name, descriptor), where name is a String and descriptor is a Property Descriptor value.

However, I don't see a definite specification for it in ECMA-262-3. Regardless, I wouldn't attempt to use non-strings as property names.

Solution 4

Here is the solution. Please tell me the environmental setups if this is not working

const screens = {
    "768": "large",
    "200": "small"
}

const keys = Object.keys(screens).map(key => parseInt(key))
                                         // OR Number(key)

console.log(keys) // Output [200, 768]

Solution 5

Do we need something like this?

var userId = 1;var myObject ={};
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);

Console: Object

1 : "a value"

Share:
123,783
Spot
Author by

Spot

I am a jack of all trades! :)

Updated on April 09, 2022

Comments

  • Spot
    Spot about 2 years

    It seems that when I use a numeric type as a key name in an object, it always gets converted to a string. Is there anyway to actually get it to store as a numeric? The normal typecasting does not seem to work.

    Example:

    var userId = 1;
    console.log( typeof userId ); // number
    myObject[userId] = 'a value';
    console.dir(myObject);
    

    Dir Output:

    {
        '1': 'a value'
    }
    

    What I want is this:

    {
        1: 'a value'
    }
    

    Advice?

  • Spot
    Spot almost 14 years
    Thanks for the response but this is not entirely accurate. A numeric will only return as 'number' from a typeof, and vice versa with a string.
  • Spot
    Spot almost 14 years
    Thank you. Is this considered a flaw in the language, or is it accepted as a good design decision?
  • Matthew Flaschen
    Matthew Flaschen almost 14 years
    That's rather subjective. As William noted, for integer keys you can instead use an array. Most JS engines can use sparse arrays behind the scenes.
  • Tim Down
    Tim Down almost 14 years
    Even in an array, all property names are converted to strings.
  • Roamer-1888
    Roamer-1888 almost 10 years
    @TimDown, that's very misleading. Array indexes and array properties are not the same thing.
  • Tim Down
    Tim Down almost 10 years
    @Roamer-1888: Not, it isn't. The only difference is that assigning a numeric property to an array affects the array's length property.
  • Roamer-1888
    Roamer-1888 almost 10 years
    @TimDown, nope that's certainly not the only difference. Javascript is not like PHP, which supports associative arrays. Javascript allows only (sparse) numeric array indexes. It also allows array properties/methods to be set/read, but they are NOT ARRAY ELEMEMTS!!!
  • Roamer-1888
    Roamer-1888 almost 10 years
    That the length property changes when array elements are added/removed, is symptomatic of the difference, not the difference itself.
  • Tim Down
    Tim Down almost 10 years
    @Roamer-1888: I'm not clear on what you're saying. All I'm saying is that the only difference between getting and setting properties when using an Array and a plain Object is that setting a numeric property on an Array can affect the length property. There is no other distinction between a property with a numeric and non-numeric name (and as I've previously mentioned, a numeric property name is converted to a string when setting the property anyway).
  • Roamer-1888
    Roamer-1888 almost 10 years
    @TimDown, and what I'm saying is that you are wrong. "Setting a numeric property on an Array can affect the length property" is an incorrect statement. Javascript Array properties are completely independent of Array elements. What confuses people is that associative syntax, eg myArray["1"] = foo, appears to be setting a property, whereas it actually sets an array element, but only because "1" is a string representation of an integer, which is complete linguistic nonsense - but that's Javascript.
  • Roamer-1888
    Roamer-1888 almost 10 years
    Meanwhile, if you were to execute myArray["myProperty"] = foo, an Array element would not be created - the property myProperty would be set on the Array, but independently of the Array elements and the length property would be unaffected. See demo. Please trust me. I may only have a rep of a few hundred here on SO, but I've been writing this stuff for close on two decades and Array basics haven't changed in that time.
  • Tim Down
    Tim Down almost 10 years
    @Roamer-1888: Your demo doesn't disprove anything I've said, and even proves that "setting a numeric property on an Array can affect the length property". I suggest reading the ECMAScript spec: array elements are just properties with special behaviour when setting.
  • Tim Down
    Tim Down almost 10 years
    @Roamer-1888: I feel the same. We might have the same understanding and just be arguing about terminology, seeing as we're both so entrenched. It bothers me and I want to know what it is you think I'm wrong about, so if you want to continue then we could do so in chat.
  • Roamer-1888
    Roamer-1888 almost 10 years
    @TimDown, too busy with a heap of other stuff. May not emerge for several days. Best wishes.
  • Hans
    Hans almost 10 years
    @Roamer-1888: "Javascript Array properties are completely independent of Array elements" is an incorrect statement. myArray["1"] = foo doesn't just appear to be setting a property, it is in fact setting a property (with a key "1") in every sense of the definition of property. Eg, myArray.hasOwnProperty("1") yields true. Semantically, this property can also be considered an "element" by virtue of having a numeric key, but there is nothing further that distinguishes an array "element" from an array property. Read the spec. If you still disagree, kindly cite your source.
  • Roamer-1888
    Roamer-1888 almost 10 years
    @Hans, this is precisely why nobody in their right mind, yourself included I hope, would attempt either to teach or to learn javascript programming from the Ecmascript specification(s), which are concerned with implementation of the language, not it usage. It is true that an array's members are properties of an underlying (concrete) object, but they are members of the (conceptual) array - not properties. It is an unfortunate shortcoming of the language that some of the underlying implementation is exposed in some of the notations available to programmers.
  • Tim Down
    Tim Down almost 10 years
    @Roamer-1888: I would rather people learned the reality of how the language works (which may well involve some reading of or reference to the spec) than one person's preconceived idea of some (actually non-existent) difference between array and object properties. It sounds like you're projecting ideas from another language onto JavaScript.
  • Hans
    Hans almost 10 years
    @TimDown Agreed. A nice feature of specs is that they allow people engaged in a technical discussion to sync up on terminology, avoiding time wasted arguing semantics.
  • mikemaccana
    mikemaccana over 6 years
    @william 'numerical strings and numbers are interchangeable' is simply not correct. Numbers are Numbers and Strings are Strings. See Object.prototype.toString.call(someObject) The issue is you can't use a Numbers as keys.
  • Reza
    Reza almost 6 years
    Please be noted that "The keys of an Object are Strings and Symbols; a symbol value may be used as an identifier for object properties" Reference
  • kaiser
    kaiser over 4 years
    The 101 of elegant Ludumdare entries! +1
  • Carmine Tambascia
    Carmine Tambascia almost 3 years
    this doesn't answer at all the question and how you see those indexes are converted in String type
  • aggregate1166877
    aggregate1166877 over 2 years
    Writing something like arr = {} is like writing myBool = 'blue'. It's almost maliciously unreadable when it comes to code maintenance and updates. A {} is not an array, it's an object. An array is written [] and calling a spade a shovel doesn't change that fact
  • aggregate1166877
    aggregate1166877 over 2 years
    Doing a shallow copy of an object just to convert keys to numbers seems like insane overkill