Existe-t-il un moyen d'utiliser un type numérique comme clé d'objet?

97

Il semble que lorsque j'utilise un type numérique comme nom de clé dans un objet, il est toujours converti en chaîne. Est-il possible de le stocker sous forme numérique? Le typage normal ne semble pas fonctionner.

Exemple:

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

Sortie Dir:

{
    '1': 'a value'
}

Ce que je veux, c'est ceci:

{
    1: 'a value'
}

Conseil?

Place
la source
Voir aussi ce commentaire - stackoverflow.com/questions/3633362/…
Manohar Reddy Poreddy le

Réponses:

109

Non, ce n'est pas possible. La clé sera toujours convertie en chaîne. Voir la documentation sur l'accesseur de propriété

Les noms de propriété doivent être des chaînes. Cela signifie que les objets sans chaîne ne peuvent pas être utilisés comme clés dans l'objet. Tout objet non-chaîne, y compris un nombre, est converti en une chaîne via la méthode toString.

> var foo = {}
undefined

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

> foo
{ '23213': 'swag' }

> typeof(Object.keys(foo)[0])
'string'
Matthew Flaschen
la source
1
C'est plutôt subjectif. Comme William l'a noté, pour les clés entières, vous pouvez à la place utiliser un tableau. La plupart des moteurs JS peuvent utiliser des baies clairsemées en arrière-plan.
Matthew Flaschen
7
Même dans un tableau, tous les noms de propriétés sont convertis en chaînes.
Tim Down
2
@ Roamer-1888: Non, ce n'est pas le cas. La seule différence est que l'attribution d'une propriété numérique à un tableau affecte la lengthpropriété du tableau .
Tim Down
2
@TimDown, et ce que je dis, c'est que vous vous trompez. «La définition d'une propriété numérique sur un tableau peut affecter la propriété de longueur» est une instruction incorrecte. Les propriétés Javascript Array sont complètement indépendantes des éléments Array. Ce qui déroute les gens, c'est que la syntaxe associative, par exemple myArray["1"] = foo, semble définir une propriété, alors qu'elle définit en fait un élément de tableau, mais uniquement parce que "1" est une représentation sous forme de chaîne d'un entier, ce qui est un non-sens linguistique complet - mais c'est Javascript.
Roamer-1888
4
@ Roamer-1888: "Les propriétés Javascript Array sont complètement indépendantes des éléments Array" est une déclaration incorrecte. myArray["1"] = foone se contente pas apparaître à définir une propriété, il est en fait de définir une propriété (avec une clé « 1 ») dans tous les sens de la définition de la propriété. Par exemple, les myArray.hasOwnProperty("1")rendements true. Sur le plan sémantique, cette propriété peut également être considérée comme un "élément" du fait qu'elle possède une clé numérique, mais il n'y a rien de plus qui distingue un tableau "élément" d'une propriété de tableau. Lisez les spécifications. Si vous n'êtes toujours pas d'accord, veuillez citer votre source.
Hans
24

Dans un objet, non, mais j'ai trouvé Map extrêmement utile pour cette application. Voici où je l'ai utilisé pour les touches numériques, un événement basé sur des clés.

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)();
  }
}
corvidé
la source
1
Les 101 entrées élégantes de Ludumdare ! +1
kaiser
11

Semble être par conception dans ECMA-262-5:

Le type d'identificateur de propriété est utilisé pour associer un nom de propriété à un descripteur de propriété. Les valeurs du type Identificateur de propriété sont des paires de la forme (nom, descripteur), où nom est une chaîne et descripteur est une valeur de descripteur de propriété.

Cependant, je ne vois pas de spécification précise pour cela dans ECMA-262-3. Quoi qu'il en soit, je n'essaierais pas d'utiliser des non-chaînes comme noms de propriété.

Rob Olmos
la source
2

Avons-nous besoin de quelque chose comme ça?

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

Console: objet

1: "une valeur"

Chittrang Mishra
la source
0

Je pense que vous pouvez faire ce qui suit si vous voulez utiliser la chose ci-dessus pour y accéder comme un numéro, j'ai fait la même chose et j'ai travaillé.

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

Cela ne fonctionne que lorsque la clé ne commence pas par un caractère numérique, sinon elle sera convertie en nombre. Consultez l'exemple suivant:

parseInt("45kjghk") === 45

J'ai utilisé jQuery ici


Actualisé:

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
}

Cela peut surmonter le problème ci-dessus. Veuillez suggérer mieux si disponible et problème avec cette réponse s'il y en a.

Shivam Sharma
la source
-3

En JavaScript, les chaînes numériques et les nombres sont interchangeables, donc

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

Si vous voulez vraiment que le nombre soit la clé d'un objet, vous voudrez peut-être un tableau (c'est-à-dire créé avec new Array()ou []).

William Niu
la source
2
Merci pour la réponse, mais ce n'est pas tout à fait exact. Un numérique ne retournera en tant que «nombre» qu'à partir d'un typeof, et vice versa avec une chaîne.
Spot le
@william «les chaînes numériques et les nombres sont interchangeables» n'est tout simplement pas correct. Les nombres sont des nombres et les chaînes sont des chaînes. Voir Object.prototype.toString.call(someObject)Le problème est que vous ne pouvez pas utiliser de nombres comme clés.
mikemaccana du