web-dev-qa-db-fra.com

Itérer dans les propriétés de l'objet

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(propt + ': ' + obj[propt]);
}

Comment la variable propt représente-t-elle les propriétés de l'objet? Ce n'est pas une méthode ou une propriété intégrée. Pourquoi trouve-t-il toutes les propriétés de l'objet?

1833
Rafay

Itérer sur les propriétés nécessite cette vérification hasOwnProperty supplémentaire:

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

Cela est nécessaire car le prototype d'un objet contient des propriétés supplémentaires pour l'objet qui font techniquement partie de l'objet. Ces propriétés supplémentaires sont héritées de la classe d'objet de base, mais restent des propriétés de obj.

hasOwnProperty vérifie simplement s'il s'agit d'une propriété spécifique à cette classe et non héritée de la classe de base.


Il est également possible d'appeler hasOwnProperty via l'objet lui-même:

if (obj.hasOwnProperty(prop)) {
    // do stuff
}

Mais cela échouera si l'objet a un champ sans rapport portant le même nom:

var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo');  // TypeError: hasOwnProperty is not a function

C'est pourquoi il est préférable de l'appeler via Object.prototype à la place:

var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo');  // true
2315
Dominik

A partir de JavaScript 1.8.5, vous pouvez utiliser Object.keys(obj) pour obtenir un tableau de propriétés définies sur l'objet lui-même (celles qui renvoient la valeur true pour obj.hasOwnProperty(key)).

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

C'est mieux (et plus lisible) que d'utiliser une boucle for-in.

Son supporté sur ces navigateurs:

  • Firefox (Gecko): 4 (2.0)
  • Chrome: 5
  • Internet Explorer: 9

Voir le réseau de développeurs Mozilla Object.keys () (référence ) pour plus d'informations.

1033
Danny R

Les filles et les gars, nous sommes en 2017 et nous n’avons pas beaucoup de temps pour taper ... Faisons donc cette nouvelle idée géniale d’ECMAScript 2016:

Object.keys(obj).forEach(e => console.log(`key=${e}  value=${obj[e]}`));
251
Frank Roth

C'est le for...in statement ( MDN , spécification ECMAScript ).

Vous pouvez le lire comme "POUR chaque propriété DANS l'objet obj, affectez chaque propriété à la variable PROPT ".

201
Marc B

Dans les prochaines versions d'ES, vous pouvez utiliser Object.entries :

_for (const [key, value] of Object.entries(obj)) { }
_

ou

_Object.entries(obj).forEach(([key, value]) => ...)
_

Si vous voulez juste parcourir les valeurs, utilisez Object.values:

_for (const value of Object.values(obj)) { }
_

ou

_Object.values(obj).forEach(value => ...)
_
97
user663031

C'est juste une boucle for...in. Découvrez la documentation sur Mozilla .

37
Matt Ball

Si votre environnement prend en charge ES2017 , je vous recommanderais Object.entries :

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

Comme indiqué dans Mozillas Object.entries () documentation:

La méthode Object.entries () renvoie un tableau des paires de propriétés énumérables propres [clé, valeur] d'un objet donné, dans le même ordre que celui fourni par une boucle for ... in (la différence étant qu'une boucle for-in énumère également les propriétés de la chaîne de prototypes).

Fondamentalement, avec Object.entries, nous pouvons ignorer l'étape supplémentaire suivante requise avec l'ancienne boucle pour ... dans :

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}
21
JSON C11

jQuery vous permet de le faire maintenant:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});
21
Rob Sedgwick

Dominik la réponse est parfaite, je préfère simplement le faire de cette façon, car c'est plus propre à lire:

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}
20
Cyril N.

Les réponses ci-dessus sont un peu gênantes car elles n'expliquent pas ce que vous faites dans la boucle for une fois que vous vous êtes assuré que c'est un objet: VOUS N'AVEZ PAS ACCÈS DIRECTEMENT! En fait, vous n’avez reçu que la clé que vous devez appliquer à l’OBJ:

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

Ceci est tout en sécurité ECMA5. Même fonctionne dans les versions boiteuses de JS comme Rhino;)

18
dylanh724

Pour ajouter l'utilisation par ES2015 de Reflect.ownKeys(obj) et également effectuer une itération sur les propriétés via un itérateur.

Par exemple:

let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };

peut être itéré par

// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));

Si vous souhaitez effectuer une itération directe sur les valeurs des clés d'un objet, vous pouvez définir un iterator, tout comme les itérateurs par défaut de JavaScipts pour les chaînes, les tableaux, les tableaux typés, Map et Set.

JS tentera une itération via la propriété par défaut d'itérateur, qui doit être définie comme étant Symbol.iterator.

Si vous voulez pouvoir parcourir tous les objets, vous pouvez l'ajouter en tant que prototype d'objet:

Object.prototype[Symbol.iterator] = function*() { 
    for(p of Reflect.ownKeys(this)){ yield this[p]; }
}

Cela vous permettrait de parcourir les valeurs d'un objet avec une boucle for ... of, par exemple:

for(val of obj) { console.log('Value is:' + val ) }

Attention: Au moment d'écrire cette réponse (juin 2018), tous les autres navigateurs, à l'exception d'IE, prennent en charge les générateurs et l'itération for...of via Symbol.iterator.

15
Dimitar Nikovski
let obj = {"a": 3, "b": 2, "6": "a"}

Object.keys(obj).map((item) => {console.log("item", obj[item])})

// a
// 3
// 2
11
Philll_t

La boucle for ... in représente chaque propriété d'un objet, car elle ressemble à une boucle for. Vous avez défini propt dans le for ... en boucle en faisant:

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

Une boucle for ... in parcourt les propriétés énumérables d'un objet. Quelle que soit la variable que vous définissez, ou mettez dans la boucle for ... in, change chaque fois qu'elle passe à la propriété suivante qu'elle itère. La variable dans la boucle for ... in parcourt les clés, mais sa valeur est celle de la clé. Par exemple:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

Vous pouvez voir en quoi la variable diffère de la valeur de la variable. En revanche, une boucle for ... of fait le contraire.

J'espère que ça aide.

11
Vappor Washmade
Object.keys(obj).forEach(key =>
  console.log(`key=${key} value=${obj[key]}`)
);
10
Fellow Stranger

Vous pouvez utiliser Lodash. La documentation

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});
10
viktarpunko

De nos jours, vous pouvez convertir un objet JS standard en un objet itérable en ajoutant simplement une méthode Symbol.iterator. Vous pouvez ensuite utiliser une boucle for of et accéder directement à ses valeurs ou même utiliser un opérateur d'étalement sur l'objet. Cool. Voyons comment nous pouvons le faire:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);
9
Redu

Votre boucle for parcourt toutes les propriétés de l'objet obj. propt est défini dans la première ligne de votre boucle for. C'est une chaîne qui est le nom d'une propriété de l'objet obj. Dans la première itération de la boucle, propt serait "name".

9
arb

Les objets en JavaScript sont des collections de propriétés et peuvent donc être bouclés dans un pour chaque instruction.

Vous devriez penser à obj comme à une collection de valeurs de clé.

9
user920041

Si vous utilisez Node, je recommanderais:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});
5
Justin

Bien que la réponse la mieux notée soit correcte, voici un autre cas d'utilisation, à savoir si vous effectuez une itération sur un objet et souhaitez créer un tableau à la fin. Utilisez .map au lieu de forEach

const newObj = Object.keys(obj).map(el => {
 //What ever you want to do
})
5
iRohitBhatia

Ajoutant également la manière récursive:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.Push(obj[property]);
                    stack.Push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

Usage:

iterate({ foo: "foo", bar: { foo: "foo"} }); 
4
Ondrej Svejdar

En gros, vous voulez parcourir chaque propriété de l'objet.

JSFiddle

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);
3
HovyTech

Ici, je répète chaque nœud et crée des noms de nœuds significatifs. Si vous remarquez que instanceOf Array et instanceOf Object font à peu près la même chose (dans mon application, je donne cependant une logique différente)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

note - Je suis inspiré par la réponse d'Ondrej Svejdar. Mais cette solution a de meilleures performances et moins ambiguë

2
Faiz Mohamed Haneef

Je veux ajouter aux réponses ci-dessus, car vous pourriez avoir des intentions différentes de Javascript. Un objet JSON et un objet Javascript sont deux choses différentes, et vous voudrez peut-être parcourir les propriétés d'un objet JSON en utilisant les solutions proposées ci-dessus, puis être surpris.

Supposons que vous ayez un objet JSON tel que:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

La mauvaise façon d'itérer à travers ses 'propriétés':

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

Vous pourriez être surpris de voir la console consigner 0, 1, etc. lors de l'itération des propriétés de prop1 et prop2 et de prop3_1. Ces objets sont des séquences et les index d'une séquence sont des propriétés de cet objet en Javascript.

n meilleur moyen de parcourir récursivement les propriétés d'un objet JSON serait tout d'abord de vérifier si cet objet est une séquence ou non:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}
2
Jadiel de Armas

L’objet de la boucle..in est qu’elle crée une nouvelle variable (var someVariable) et stocke ensuite chaque propriété de l’objet donné dans cette nouvelle variable (someVariable) une par une. Par conséquent, si vous utilisez le bloc {}, vous pouvez effectuer une itération. Prenons l'exemple suivant.

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet
2
Raman Sohi

Pour affiner davantage la réponse acceptée, il convient de noter que si vous instanciez l'objet avec un var object = Object.create(null), alors object.hasOwnProperty(property) déclenchera une TypeError. Donc, pour être sûr, vous devez l'appeler à partir du prototype comme ceci:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}
1
Konrad Kiss