Gibt es eine Möglichkeit, einen numerischen Typ als Objektschlüssel zu verwenden?


96

Es scheint, dass wenn ich einen numerischen Typ als Schlüsselnamen in einem Objekt verwende, dieser immer in eine Zeichenfolge konvertiert wird. Gibt es überhaupt eine Möglichkeit, es tatsächlich als Zahl zu speichern? Das normale Typecasting scheint nicht zu funktionieren.

Beispiel:

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

Dir Output:

{
    '1': 'a value'
}

Was ich will ist folgendes:

{
    1: 'a value'
}

Rat?


Antworten:


107

Nein das ist nicht möglich. Der Schlüssel wird immer in eine Zeichenfolge konvertiert. Siehe Property Accessor-Dokumente

Eigenschaftsnamen müssen Zeichenfolgen sein. Dies bedeutet, dass Nicht-String-Objekte nicht als Schlüssel im Objekt verwendet werden können. Jedes Nicht-String-Objekt, einschließlich einer Zahl, wird über die toString-Methode in einen String typisiert.

> var foo = {}
undefined

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

> foo
{ '23213': 'swag' }

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

1
Das ist eher subjektiv. Wie William bemerkte, können Sie für Ganzzahlschlüssel stattdessen ein Array verwenden. Die meisten JS-Engines können hinter den Kulissen spärliche Arrays verwenden.
Matthew Flaschen

6
Selbst in einem Array werden alle Eigenschaftsnamen in Zeichenfolgen konvertiert.
Tim Down

2
@ Roamer-1888: Nicht, ist es nicht. Der einzige Unterschied besteht darin, dass das Zuweisen einer numerischen Eigenschaft zu einem Array die Eigenschaft des Arrays beeinflusst length.
Tim Down

2
@ TimDown, und was ich sage ist, dass Sie falsch liegen. "Das Festlegen einer numerischen Eigenschaft in einem Array kann sich auf die Länge auswirken" ist eine falsche Aussage. Javascript-Array-Eigenschaften sind völlig unabhängig von Array-Elementen. Was die Menschen verwirrt ist , dass assoziative Syntax, zB myArray["1"] = foo, erscheint eine Eigenschaft zu Einstellung, während es tatsächlich ein Array - Element enthält, aber nur , weil „1“ ist eine String - Darstellung einer ganzen Zahl, die eine vollständige linguistische nonsense ist - aber das ist Javascript.
Roamer-1888

4
@ Roamer-1888: "Javascript-Array-Eigenschaften sind völlig unabhängig von Array-Elementen" ist eine falsche Aussage. myArray["1"] = foonicht nur erscheint eine Eigenschaft zu Einstellung, ist es in der Tat eine Eigenschaft festlegen (mit der Taste „1“) in jedem Sinne des Wortes von Eigentum. ZB myArray.hasOwnProperty("1")ergibt true. Semantisch kann diese Eigenschaft aufgrund eines numerischen Schlüssels auch als "Element" betrachtet werden, aber es gibt nichts weiter, was ein Array "Element" von einer Array-Eigenschaft unterscheidet. Lesen Sie die Spezifikation. Wenn Sie immer noch nicht einverstanden sind, geben Sie bitte Ihre Quelle an.
Hans

23

In einem Objekt, nein, aber ich habe Map als äußerst nützlich für diese Anwendung empfunden. Hier habe ich es für numerische Schlüssel verwendet, ein schlüsselbasiertes Ereignis.

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)();
  }
}

1
Die 101 eleganten Ludumdare- Einträge! +1
Kaiser

11

Scheint in ECMA-262-5 beabsichtigt zu sein:

Der Typ Property Identifier wird verwendet, um einen Property Name einem Property Descriptor zuzuordnen. Werte vom Typ Property Identifier sind Paare der Form (Name, Deskriptor), wobei name eine Zeichenfolge und Deskriptor ein Property Descriptor-Wert ist.

In ECMA-262-3 sehe ich jedoch keine definitive Spezifikation dafür. Unabhängig davon würde ich nicht versuchen, Nicht-Strings als Eigenschaftsnamen zu verwenden.


2

Brauchen wir so etwas?

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

Konsole: Objekt

1: "ein Wert"


0

Ich denke, Sie können Folgendes tun, wenn Sie das oben genannte Ding für den Zugriff wie eine Nummer verwenden möchten. Ich habe das Gleiche getan und gearbeitet.

var myObj = {"0":"a","1":"b","CNT":2};
$.each(myObj,function(key,value){
     if(isNaN(parseInt(key))){
          return true; //continue;
     }
     //Code to perform operation
}

Dies funktioniert nur, wenn der Schlüssel nicht mit einem numerischen Zeichen beginnt, da er sonst in eine Zahl umgewandelt wird. Siehe folgendes Beispiel:

parseInt("45kjghk") === 45

Ich habe hier jQuery verwendet


Aktualisiert:

var myObj = {"0":"a","1":"b","CNT":2};
$.each(myObj,function(key,value){
     if(isNaN(parseInt(key)) || (key.length !== parseInt(key).toString().length) ){
          return true; //continue;
     }
     //Code to perform operation
}

Es kann das obige Problem überwinden. Bitte schlagen Sie besser vor, falls verfügbar, und geben Sie ein Problem mit dieser Antwort an, falls vorhanden.


-3

In JavaScript sind numerische Zeichenfolgen und Zahlen also austauschbar

myObject[1] == myObject['1']

Wenn Sie wirklich möchten, dass die Zahl der Schlüssel für ein Objekt ist, möchten Sie möglicherweise ein Array (dh mit new Array()oder erstellt []).


2
Vielen Dank für die Antwort, aber dies ist nicht ganz richtig. Eine Zahl wird nur als 'Zahl' von einem Typ zurückgegeben und umgekehrt mit einer Zeichenfolge.
Spot

@william 'numerische Zeichenfolgen und Zahlen sind austauschbar' ist einfach nicht korrekt. Zahlen sind Zahlen und Strings sind Strings. Siehe Object.prototype.toString.call(someObject)Das Problem ist, dass Sie keine Zahlen als Schlüssel verwenden können.
Mikemaccana
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.