110 votes

Accéder aux propriétés non numériques d'un objet par index ?

Si j'ai un tableau comme celui-ci :

var arr = ['one','two','three'];

Je peux ainsi accéder à différentes parties :

console.log(arr[1]);

Comment puis-je accéder aux propriétés d'un objet par leur ordre plutôt que par leur clé ?

Exemple :

var obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
},
jbo = {
    'evenmore'  : 'crazy',
    'something' : 'awesome'
};

Comment puis-je obtenir la première propriété de chaque objet - "quelque chose" de obj et "evenmore" de jbo -sans utiliser explicitement le nom de la propriété ?

Certains d'entre vous semblent penser que je cherche quelque chose comme.. :

console.log(obj['something']);

Ce n'est pas le cas, je cherche spécifiquement à cibler l'index, comme dans le premier exemple - si c'est possible.

145voto

user113716 Points 143363

"Je cherche spécifiquement à cibler l'indice, comme dans le premier exemple - si c'est possible.

Non, ce n'est pas possible.

Le plus proche est d'obtenir un tableau des clés de l'objet et de l'utiliser :

var keys = Object.keys( obj );

...mais il n'y a aucune garantie que les clés seront renvoyées dans l'ordre que vous avez défini. Cela pourrait donc ressembler à ce qui suit :

keys[ 0 ];  // 'evenmore'
keys[ 1 ];  // 'something'

53voto

0x499602D2 Points 36421

La seule façon d'y parvenir est de créer une méthode qui vous donne la propriété à l'aide de Object.keys(); .

var obj = {
    dog: "woof",
    cat: "meow",
    key: function(n) {
        return this[Object.keys(this)[n]];
    }
};
obj.key(1); // "meow"

Démonstration : http://jsfiddle.net/UmkVn/

Il serait possible d'étendre ce principe à tous les objets en utilisant la fonction Object.prototype; mais ce n'est généralement pas recommandé.

Utilisez plutôt une fonction d'aide :

var object = {
  key: function(n) {
    return this[ Object.keys(this)[n] ];
  }
};

function key(obj, idx) {
  return object.key.call(obj, idx);
}

key({ a: 6 }, 0); // 6

20voto

Arthur Senna Points 181

Vous pouvez utiliser le Object.values() si vous ne voulez pas utiliser la méthode Object.keys() .

Par opposition à la Object.keys() qui renvoie un tableau des propriétés énumérables d'un objet donné :

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.keys(object1));

imprimerait le tableau suivant :

[ 'a', 'b', 'c' ]

En Object.values() renvoie un tableau des propriétés énumérables d'un objet donné. values .

Ainsi, si vous avez le même objet mais que vous utilisez des valeurs à la place,

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.values(object1));

Vous obtiendrez le tableau suivant :

[ 'somestring', 42, false ]

Ainsi, si vous souhaitez accéder au object1.b mais en utilisant un index à la place, vous pourriez utiliser :

Object.values(object1)[1] === 42

Pour en savoir plus sur cette méthode aquí .

5voto

cuzzea Points 1279
var obj = {
    'key1':'value',
    '2':'value',
    'key 1':'value'
}

console.log(obj.key1)
console.log(obj['key1'])
console.log(obj['2'])
console.log(obj['key 1'])

// will not work
console.log(obj.2)

Edita:

"Je cherche spécifiquement à cibler l'indice, comme dans le premier exemple - si c'est possible.

En fait, c'est l'"index" qui est la clé. Si vous souhaitez stocker la position d'une clé, vous devez créer un objet personnalisé pour le gérer.

3voto

Bikram Kumar Points 132

Oui, c'est possible . Nous pouvons définir getters pour chaque indice et renvoie la valeur de la propriété dans la méthode du constructeur de la classe. Voir ce code.

class className {
  constructor() {
    this.name = "Bikram";
    this.age = 8;
    this.x = 89;
    this.y = true;

//Use a for loop and define the getters (with the object property's index as its "name") for each property using Object.defineProperty()

    for (let i = 0; i < Object.keys(this).length; i++) {

      Object.defineProperty(this, i, {
        get: function() {
          return Object.values(this)[i]}
      });
    }

  }
}

var b = new className();
console.log(b[0]); // same as b.name ("Bikram")
console.log(b[1]); // = b.age (8)
console.log(b[2]); // = b.x (89)
console.log(b[3]); // = b.y (true)

Edita: Si vous souhaitez modifier les propriétés en fonction de leurs indices, ce qui est bien sûr le cas. Il suffit alors de définir un setter pour chaque bien dans le Object.defineProperty() méthode. Elle se présentera comme suit :

// Insert this in place of the old one 

     Object.defineProperty(this, i, {
       get: function() {
          return Object.values(this)[i];
        },
        set: function(newValue) {
          this[Object.keys(this)[i]] = newValue;
        }
     })

     console.log(b[0]); // "Bikram"

     b[0] = "Bikram Kumar";

     console.log(b[0]); // "Bikram Kumar"

Et maintenant vous avez un "objet de type tableau" dont les propriétés peuvent être accédées ou modifiées soit par la clé de la propriété, soit par son index :D

Une remarque en passant : Notez que Object.keys() et Object.values() ne renvoie que le propriétés énumérables . Si vous vous contentez de déclarer une propriété sans lui attribuer de valeur, la fonction Object.[key/value]s() le laisseront dans le tableau retourné, car par défaut ils ne sont pas énumérables. Cela peut prêter à confusion pour les indices ainsi définis (sauf dans le cas où la propriété non déclarée est la dernière).

Pour contourner ce problème, il existe un moyen simple, si vous voulez qu'une propriété ait un index, mais que vous ne voulez pas l'assigner maintenant. Il suffit de lui donner la valeur undefined et il sera désormais énumérable, et les indices ne seront pas affectés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X