Question Comment parcourir ou énumérer un objet JavaScript?


J'ai un objet JavaScript comme celui-ci:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Maintenant, je veux traverser tout p éléments (p1,p2,p3...) et obtenir leurs clés et leurs valeurs. Comment puis je faire ça?

Je peux modifier l'objet JavaScript si nécessaire. Mon but ultime est de faire une boucle à travers certaines paires de valeurs clés et si possible, je veux éviter d'utiliser eval.


2129
2018-03-26 06:01


origine


Réponses:


Vous pouvez utiliser le for-in boucle comme indiqué par d'autres. Cependant, vous devez également vous assurer que la clé que vous obtenez est une propriété réelle d'un objet et qu'elle ne provient pas du prototype.

Voici l'extrait:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}


3460
2018-03-26 06:12



Sous ECMAScript 5, vous pouvez combiner Object.keys() et Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ES6 ajoute for...of:

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ES2017 ajoute Object.entries() ce qui évite d'avoir à rechercher chaque valeur dans l'objet original:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

Tous les deux Object.keys() et Object.entries() itérer propriétés dans le même ordre que for...in boucle mais ignorer la chaîne de prototype. Seules les propriétés énumérables de l'objet sont itérées.

Edit: ES2016 → ES6


621
2018-04-20 21:59



Vous devez utiliser le Boucle for-in

Mais soyez très prudent lorsque vous utilisez ce type de boucle, car cela va boucle toutes les propriétés le long de la chaîne du prototype.

Par conséquent, lorsque vous utilisez des boucles for-in, utilisez toujours le hasOwnProperty méthode pour déterminer si la propriété en cours d'itération est réellement une propriété de l'objet que vous vérifiez:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}

300
2018-03-26 06:12



La question ne sera pas complète si nous ne mentionnons pas de méthodes alternatives pour faire une boucle sur des objets.

De nos jours, de nombreuses bibliothèques JavaScript bien connues fournissent leurs propres méthodes pour itérer sur des collections, c'est-à-dire sur tableaux, objets, et objets de type tableau. Ces méthodes sont pratiques à utiliser et entièrement compatibles avec n'importe quel navigateur.

  1. Si vous travaillez avec jQuery, vous pouvez utiliser jQuery.each() méthode. Il peut être utilisé pour itérer de manière transparente sur les objets et les tableaux:

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. Dans Underscore.js vous pouvez trouver la méthode _.each(), qui itére sur une liste d'éléments, cédant chacun à son tour à une fonction fournie (attention à l'ordre des arguments dans itérer fonction!):

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dash fournit plusieurs méthodes d'itération sur les propriétés de l'objet. De base _.forEach() (ou c'est un alias _.each()) est utile pour faire une boucle entre les objets et les tableaux, cependant (!) les objets avec length les propriétés sont traitées comme des tableaux, et pour éviter ce comportement, il est suggéré d'utiliser _.forIn() et _.forOwn() méthodes (celles-ci ont aussi value argument venant en premier):

    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn() itère sur propre et hérité propriétés énumérables d'un objet, tandis que _.forOwn() itère seulement sur posséder propriétés d'un objet (essentiellement contre hasOwnProperty fonction). Pour les objets simples et les littéraux d'objet, aucune de ces méthodes ne fonctionnera correctement.

En général, toutes les méthodes décrites ont le même comportement avec tous les objets fournis. En plus d'utiliser natif for..in boucle sera généralement plus rapide que toute abstraction, comme jQuery.each(), ces méthodes sont considérablement plus faciles à utiliser, nécessitent moins de codage et offrent une meilleure gestion des erreurs.


230
2018-01-20 17:58



Dans ECMAScript 5 vous avez une nouvelle approche dans les champs d'itération littérale - Object.keys

Plus d'informations que vous pouvez voir sur MDN

Mon choix est ci-dessous comme une solution plus rapide dans les versions actuelles des navigateurs (Chrome30, IE10, FF25)

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

Vous pouvez comparer les performances de cette approche avec différentes implémentations sur jsperf.com:

Le support du navigateur que vous pouvez voir sur La table de compat de Kangax

Pour l'ancien navigateur, vous avez simple et plein polyfill

UPD:

comparaison des performances pour tous les cas les plus populaires dans cette question sur perfjs.info:

l'itération littérale d'objet


47
2017-11-16 19:59



Vous pouvez juste itérer dessus comme:

for (var key in p) {
  alert(p[key]);
}

Notez que key ne prendra pas la valeur de la propriété, c'est juste une valeur d'index.


30
2018-03-26 06:05



Depuis es2015 devient de plus en plus populaire, je poste cette réponse, qui comprend l'utilisation de générateur et itérateur pour itérer doucement à travers [key, value] paires. Comme c'est possible dans d'autres langues, par exemple Ruby.

Ok, voici un code:

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
  [Symbol.iterator]: function* () {
    for (const i of Object.keys(this)) {
      yield [i, this[i]];
    }
  }
};

for (const [k, v] of MyObject) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Toutes les informations sur la façon dont vous pouvez faire un itérateur et un générateur, vous pouvez trouver à la page développeur Mozilla.

J'espère que ça a aidé quelqu'un.

MODIFIER:

ES2017 inclura Object.entries ce qui rendra itératif [key, value] paires dans des objets encore plus facile. On sait maintenant qu'il fera partie d'une norme selon le ts39 informations sur la scène.

Je pense qu'il est temps de mettre à jour ma réponse pour qu'elle devienne encore plus fraîche que maintenant.

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Vous pouvez en savoir plus sur l'utilisation sur MDN page


24
2017-08-27 09:06



via prototype avec pour chaque() qui devrait sauter le chaîne de prototypes Propriétés:

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3

17
2017-12-09 05:05



Après avoir parcouru toutes les réponses ici, hasOwnProperty n'est pas nécessaire pour mon propre usage car mon objet json est propre; il n'y a vraiment aucun sens à ajouter un traitement javascript supplémentaire. C'est tout ce que j'utilise:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}

14
2017-08-18 20:50