Is there any way to use a numeric type as an object key?
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"
Comments
-
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?
-
Manohar Reddy Poreddy over 4 yearsAlso see this comment - stackoverflow.com/questions/3633362/…
-
-
Spot almost 14 yearsThanks 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 almost 14 yearsThank you. Is this considered a flaw in the language, or is it accepted as a good design decision?
-
Matthew Flaschen almost 14 yearsThat'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 almost 14 yearsEven in an array, all property names are converted to strings.
-
Roamer-1888 almost 10 years@TimDown, that's very misleading. Array indexes and array properties are not the same thing.
-
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 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 almost 10 yearsThat the length property changes when array elements are added/removed, is symptomatic of the difference, not the difference itself.
-
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 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 almost 10 yearsMeanwhile, if you were to execute
myArray["myProperty"] = foo
, an Array element would not be created - the propertymyProperty
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 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 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 almost 10 years@TimDown, too busy with a heap of other stuff. May not emerge for several days. Best wishes.
-
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")
yieldstrue
. 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 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 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 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 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 almost 6 yearsPlease 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 over 4 yearsThe 101 of elegant Ludumdare entries! +1
-
Carmine Tambascia almost 3 yearsthis doesn't answer at all the question and how you see those indexes are converted in String type
-
aggregate1166877 over 2 yearsWriting something like
arr = {}
is like writingmyBool = '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 over 2 yearsDoing a shallow copy of an object just to convert keys to numbers seems like insane overkill