Esiste un modo per utilizzare un tipo numerico come chiave oggetto?


97

Sembra che quando utilizzo un tipo numerico come nome chiave in un oggetto, venga sempre convertito in una stringa. C'è comunque per farlo effettivamente memorizzare come un numero? Il normale typecasting non sembra funzionare.

Esempio:

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

Uscita Dir:

{
    '1': 'a value'
}

Quello che voglio è questo:

{
    1: 'a value'
}

Consigli?


Risposte:


109

No, non è possibile. La chiave verrà sempre convertita in una stringa. Vedere la documentazione di Property Accessor

I nomi delle proprietà devono essere stringhe. Ciò significa che gli oggetti non stringa non possono essere utilizzati come chiavi nell'oggetto. Qualsiasi oggetto non stringa, incluso un numero, viene trasformato in una stringa tramite il metodo toString.

> var foo = {}
undefined

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

> foo
{ '23213': 'swag' }

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

1
È piuttosto soggettivo. Come ha notato William, per le chiavi intere puoi invece usare un array. La maggior parte dei motori JS può utilizzare array sparsi dietro le quinte.
Matthew Flaschen

7
Anche in un array, tutti i nomi di proprietà vengono convertiti in stringhe.
Tim Down

2
@ Roamer-1888: No, non lo è. L'unica differenza è che l'assegnazione di una proprietà numerica a un array influisce sulla lengthproprietà dell'array .
Tim Down

2
@ TimDown, e quello che sto dicendo è che ti sbagli. "L'impostazione di una proprietà numerica su un array può influire sulla proprietà length" è un'istruzione errata. Le proprietà degli array Javascript sono completamente indipendenti dagli elementi dell'array. Ciò che confonde le persone è che la sintassi associativa, ad esempio myArray["1"] = foo, sembra impostare una proprietà, mentre in realtà imposta un elemento di matrice, ma solo perché "1" è una rappresentazione di stringa di un numero intero, che è una completa assurdità linguistica - ma questo è Javascript.
Roamer-1888

4
@ Roamer-1888: "Le proprietà dell'array Javascript sono completamente indipendenti dagli elementi dell'array" è un'affermazione errata. myArray["1"] = foonon sembra solo impostare una proprietà, è in effetti impostare una proprietà (con una chiave "1") in tutti i sensi della definizione di proprietà. Ad esempio, myArray.hasOwnProperty("1")rendimenti true. Semanticamente, questa proprietà può anche essere considerata un "elemento" in virtù del fatto di avere una chiave numerica, ma non c'è niente di più che distingua un "elemento" di array da una proprietà di array. Leggi le specifiche. Se ancora non sei d'accordo, cita gentilmente la tua fonte.
Hans

24

In un oggetto no, ma ho trovato Map estremamente utile per questa applicazione. Qui è dove l'ho usato per i tasti numerici, un evento basato su chiave.

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
La 101 delle eleganti voci Ludumdare ! +1
kaiser

11

Sembra essere in base alla progettazione in ECMA-262-5:

Il tipo di identificatore di proprietà viene utilizzato per associare un nome di proprietà a un descrittore di proprietà. I valori del tipo di identificatore di proprietà sono coppie della forma (nome, descrittore), dove nome è una stringa e descrittore è un valore di descrittore di proprietà.

Tuttavia, non vedo una specifica precisa per questo in ECMA-262-3. Indipendentemente da ciò, non tenterei di utilizzare non stringhe come nomi di proprietà.


2

Abbiamo bisogno di qualcosa di simile?

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

Console: oggetto

1: "un valore"


0

Penso che tu possa fare quanto segue se vuoi usare la cosa sopra per accedervi come un numero, ho fatto lo stesso e ho lavorato.

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

Funziona solo quando la chiave non inizia con un carattere numerico, altrimenti verrà convertito in un numero. Vedi il seguente esempio:

parseInt("45kjghk") === 45

Ho usato jQuery qui


Aggiornato:

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
}

Può superare il problema di cui sopra. Si prega di suggerire meglio se disponibile e problema con questa risposta se ci sono.


-3

In JavaScript, stringhe numeriche e numeri sono intercambiabili, quindi

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

Se vuoi davvero che il numero sia la chiave per un oggetto, potresti volere un array (cioè creato con new Array()o []).


2
Grazie per la risposta, ma non è del tutto esatto. Un valore numerico restituirà solo come 'numero' da un tipo di e viceversa con una stringa.
Spot

@william "stringhe numeriche e numeri sono intercambiabili" semplicemente non è corretto. I numeri sono numeri e le stringhe sono stringhe. Vedi Object.prototype.toString.call(someObject)Il problema è che non puoi usare i numeri come chiavi.
mikemaccana
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.