J'ai un objet JavaScript comme le suivant:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Maintenant , je veux faire une boucle à travers tous les p
éléments ( p1
, p2
, p3
...) et obtenir les clés et les valeurs. Comment puis je faire ça?
Je peux modifier l'objet JavaScript si nécessaire. Mon objectif ultime est de parcourir certaines paires de valeurs clés et, si possible, je veux éviter de les utiliser eval
.
javascript
loops
for-loop
each
Tanmoy
la source
la source
Réponses:
Vous pouvez utiliser la
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:
For-of avec une alternative Object.keys ():
Remarquez l'utilisation de
for-of
au lieu defor-in
, s'il n'est pas utilisé, il renverra undefined sur les propriétés nommées etObject.keys()
garantit l'utilisation des seules propriétés de l'objet sans les propriétés de la chaîne de prototype entièresEn utilisant la nouvelle
Object.entries()
méthode:Remarque: Cette méthode n'est pas prise en charge nativement par Internet Explorer. Vous pouvez envisager d'utiliser un Polyfill pour les anciens navigateurs.
la source
alert(key + " -> " + JSON.stringify(p[key]));
__proto__
ouprototype
. Cette propriété a une référence à son objet parent. Un objet hérite automatiquement de la propriété de son parent. C'est la raison de l'utilisationhasOwnProperty
, ce qui signifie que nous nous intéressons aux propriétés des objets et non à leurs propriétés parentales.Sous ECMAScript 5, vous pouvez combiner
Object.keys()
etArray.prototype.forEach()
:ECMAScript 6 ajoute
for...of
:ECMAScript 8 ajoute
Object.entries()
ce qui évite d'avoir à rechercher chaque valeur dans l'objet d'origine:Vous pouvez combiner
for...of
, déstructurer etObject.entries
:Les deux
Object.keys()
etObject.entries()
itèrent les propriétés dans le même ordre qu'unefor...in
boucle, mais ignorent la chaîne prototype . Seules les propriétés énumérables de l'objet sont itérées.la source
Object.forEach(obj, function (value, key) {...})
? :( Ceobj.forEach(function...)
serait certainement plus court et complémentaireArray.prototype.forEach
, mais cela risquerait de faire en sorte que les objets définissent leur propreforEach
propriété. Je suppose qu'ilObject.keys
protège contre le rappel modifiant les clés de l'objet.Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); }
Object.entries(obj).map/forEach(([key, value]) => console.log(key, value))
([clé, valeur] est la déstructuration du tableau, pour accéder directement aux deux éléments. Et vous devez encapsuler les paramètres dans des parenthèses supplémentaires.)index
la clé dans json? Ou si nécessaire, dois-je utiliser un compteur séparé?for...of
est la norme ES6, pas ES2016.Vous devez utiliser la boucle for-in
Mais soyez très prudent lorsque vous utilisez ce type de boucle, car cela bouclera 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 la
hasOwnProperty
méthode pour déterminer si la propriété actuelle dans l'itération est vraiment une propriété de l'objet que vous vérifiez:la source
{ }
personnellement parce qu'unif
sans eux rend peu clair ce qui fait partie deif
ce qui ne l'est pas. Mais je suppose que ce n'est qu'une question d'opinion :){ }
principalement pour éviter toute confusion si l'on a besoin plus tard d'ajouter quelque chose à laif
portée.Object.prototype.hasOwnProperty.call(p, prop)
Cependant, cela ne peut pas non plus protéger contre les manipulations de Object.prototype ...La question ne sera pas complète si nous ne mentionnons pas de méthodes alternatives pour parcourir les objets.
De nos jours, de nombreuses bibliothèques JavaScript bien connues fournissent leurs propres méthodes d'itération sur des collections, c'est-à-dire sur des tableaux , des objets et des objets de type tableau . Ces méthodes sont pratiques à utiliser et sont entièrement compatibles avec n'importe quel navigateur.
Si vous travaillez avec jQuery , vous pouvez utiliser la
jQuery.each()
méthode. Il peut être utilisé pour itérer de manière transparente sur les objets et les tableaux:Dans Underscore.js, vous pouvez trouver une méthode
_.each()
, qui itère sur une liste d'éléments, donnant chacun à son tour à une fonction fournie (faites attention à l'ordre des arguments dans la fonction iteratee !):Lo-Dash propose plusieurs méthodes pour itérer sur les propriétés des objets. Basic
_.forEach()
(ou son alias_.each()
) est utile pour parcourir à la fois les objets et les tableaux, mais (!) Les objets aveclength
propriété sont traités comme des tableaux, et pour éviter ce comportement, il est suggéré d'utiliser les méthodes_.forIn()
et_.forOwn()
(elles ont également l'value
argument en premier):_.forIn()
itère sur les propriétés énumérables propres et héritées d'un objet, tandis qu'il_.forOwn()
itère uniquement sur les propriétés propres d'un objet (essentiellement enhasOwnProperty
fonction de la fonction). Pour les objets simples et les littéraux d'objets, n'importe laquelle de ces méthodes fonctionnera correctement.Généralement, toutes les méthodes décrites ont le même comportement avec tous les objets fournis. En plus d'utiliser une
for..in
boucle native sera généralement plus rapide que n'importe quelle abstraction, par exemplejQuery.each()
, ces méthodes sont considérablement plus faciles à utiliser, nécessitent moins de codage et offrent une meilleure gestion des erreurs.la source
Dans ECMAScript 5, vous avez une nouvelle approche dans les domaines d'itération du littéral -
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)
Vous pouvez comparer les performances de cette approche avec différentes implémentations sur jsperf.com :
Prise en charge du navigateur que vous pouvez voir sur la table compat de Kangax
Pour les anciens navigateurs, vous disposez d' un polyfill simple et complet
UPD:
comparaison des performances pour tous les cas les plus populaires dans cette question sur
perfjs.info
:itération littérale d'objet
la source
Préface:
Ici, en 2018, vos options pour parcourir les propriétés d'un objet sont (certains exemples suivent la liste):
for-in
[ MDN , spec ] - Une structure de boucle qui parcourt les noms des propriétés énumérables d'un objet , y compris celles héritées, dont les noms sont des chaînesObject.keys
[ MDN , spec ] - Une fonction fournissant un tableau des noms de d'un objet propre , dénombrables propriétés dont les noms sont des chaînes.Object.values
[ MDN , spec ] - Une fonction fournissant un tableau des valeurs de l' objet d'un propre , dénombrables propriétés.Object.entries
[ MDN , spec ] - Une fonction fournissant un tableau des noms et des valeurs de d'un objet propre , dénombrables propriétés (chaque entrée de la matrice est une[name, value]
matrice).Object.getOwnPropertyNames
[ MDN , spec ] - Une fonction fournissant un tableau des noms d'un objet de propres propriétés (même les non-dénombrables) dont les noms sont des chaînes.Object.getOwnPropertySymbols
[ MDN , spec ] - Une fonction fournissant un tableau des noms d'un objet de propres propriétés (même les non-dénombrables) dont les noms sont des symboles.Reflect.ownKeys
[ MDN , spec ] - Une fonction fournissant un tableau des noms d'un objet de propres propriétés (même les non-dénombrables), que ces noms sont des chaînes ou des symboles.Object.getPrototypeOf
[ MDN , spécifications ] et l' utilisationObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
ouReflect.ownKeys
sur chaque objet dans la chaîne de prototype ( par exemple au bas de cette réponse).Avec tous sauf
for-in
, vous utiliseriez une sorte de boucle construction sur le tableau (for
,for-of
,forEach
, etc.).Exemples:
for-in
:Afficher l'extrait de code
Object.keys
(avec unefor-of
boucle, mais vous pouvez utiliser n'importe quelle construction en boucle) :Afficher l'extrait de code
Object.values
:Afficher l'extrait de code
Object.entries
:Afficher l'extrait de code
Object.getOwnPropertyNames
:Afficher l'extrait de code
Object.getOwnPropertySymbols
:Afficher l'extrait de code
Reflect.ownKeys
:Afficher l'extrait de code
Toutes les propriétés , y compris les propriétés non énumérables héritées:
Afficher l'extrait de code
la source
Vous pouvez simplement itérer dessus comme:
Notez que
key
cela ne prendra pas la valeur de la propriété, c'est juste une valeur d'index.la source
Depuis que es2015 devient de plus en plus populaire, je publie cette réponse qui inclut l'utilisation du générateur et de l'itérateur pour itérer en douceur par
[key, value]
paires. Comme c'est possible dans d'autres langues, par exemple Ruby.Ok voici un code:
Toutes les informations sur la façon dont vous pouvez faire un itérateur et un générateur que vous pouvez trouver sur la page Mozilla du développeur.
J'espère que cela a aidé quelqu'un.
ÉDITER:
ES2017 inclura
Object.entries
ce qui rendra l'itération sur des[key, value]
paires d'objets encore plus facile. On sait maintenant qu'il fera partie d'une norme selon les informations d'étape ts39 .Je pense qu'il est temps de mettre à jour ma réponse pour la laisser devenir encore plus fraîche qu'elle ne l'est maintenant.
Vous pouvez trouver plus d'informations sur l'utilisation sur la page MDN
la source
Remarque: vous pouvez le faire sur des tableaux, mais vous parcourrez également les
length
propriétés et d'autres.la source
key
prendra simplement une valeur d'index, ce qui alertera simplement 0, 1, 2, etc.var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
fait apparaître "p1" et "p2" dans les alertes, alors qu'est-ce qui ne va pas ???Après avoir parcouru toutes les réponses ici, hasOwnProperty n'est pas requis 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:
la source
Object.prototype
, elle sera énumérée parfor..in
. Si vous êtes sûr de ne pas utiliser de bibliothèques pour cela, vous n'avez pas besoin d'appelerhasOwnProperty
.Object.create(null)
via prototype avec forEach () qui devrait ignorer les propriétés de la chaîne de prototype :
la source
obj = { print: 1, each: 2, word: 3 }
produitTypeError: number is not a function
. UtiliserforEach
pour faire correspondre laArray
fonction similaire peut réduire quelque peu le risque.Il est intéressant que les personnes dans ces réponses aient abordé les deux
Object.keys()
etfor...of
ne les aient jamais combinées:Vous ne pouvez pas juste
for...of
unObject
parce que ce n'est pas un itérateur, etfor...index
ou.forEach()
ingObject.keys()
est laid / inefficace.Je suis content que la plupart des gens s'abstiennent
for...in
(avec ou sans vérification.hasOwnProperty()
) car c'est aussi un peu compliqué, donc à part ma réponse ci-dessus, je suis ici pour dire ...Vous pouvez faire itérer les associations d'objets ordinaires! Se
Map
comporter comme des s avec une utilisation directe dufor...of
DEMO sophistiqué fonctionnant dans Chrome et FF (je suppose que ES6 uniquement)
Tant que vous incluez ma cale ci-dessous:
Sans avoir à créer un véritable objet Map qui n'a pas le bon sucre syntaxique.
En fait, avec ce shim, si vous vouliez toujours profiter des autres fonctionnalités de Map (sans les caler toutes), mais vouliez toujours utiliser la notation d'objet soignée, puisque les objets sont maintenant itérables, vous pouvez maintenant simplement en faire une Map!
Pour ceux qui n'aiment pas faire de shim, ou jouer avec
prototype
en général, n'hésitez pas à faire la fonction sur la fenêtre à la place, en l'appelant quelque chose comme çagetObjIterator()
;Maintenant, vous pouvez simplement l'appeler comme une fonction ordinaire, rien d'autre n'est affecté
ou
Il n'y a aucune raison pour que cela ne fonctionne pas.
Bienvenue dans le futur.
la source
For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
ordinaryObject
pour souligner que la magie fonctionne toujours pour ces types). Avez-vous vérifié les démos; qu'est-ce qui ne fonctionne pas pour vous, @ noɥʇʎԀʎzɐɹƆ? (PS, votre image de profil SE est le patron)Il donne donc la même liste de clés que vous souhaitez en testant chaque clé d'objet avec hasOwnProperty. Vous n'avez pas besoin de cette opération de test supplémentaire et
Object.keys( obj ).forEach(function( key ){})
vous êtes censé être plus rapide. Prouvons-le:Dans mon Firefox, j'ai les résultats suivants
PS. sur Chrome, la différence est encore plus grande http://codepen.io/dsheiko/pen/JdrqXa
PS2: Dans ES6 (EcmaScript 2015), vous pouvez parcourir plus facilement un objet itérable:
la source
of
sans créer deMap
sVoici une autre méthode pour parcourir un objet.
la source
for
méthode peut être plus performante.la source
Vous pouvez également utiliser Object.keys () et parcourir les clés d'objet comme ci-dessous pour obtenir la valeur:
la source
Uniquement du code JavaScript sans dépendances:
la source
La
Object.keys()
méthode renvoie un tableau des propres propriétés énumérables d'un objet donné. En savoir plus icila source
Performance
Aujourd'hui 2020.03.06 j'effectue des tests des solutions choisies sur Chrome v80.0, Safari v13.0.5 et Firefox 73.0.1 sur MacOs High Sierra v10.13.6
Conclusions
for-in
(A, B) sont rapides (ou les plus rapides) pour tous les navigateurs pour petits et grands objetsfor-of
(H), la solution est rapide sur le chrome pour les petits et les gros objetsi
(J, K) sont assez rapides sur tous les navigateurs pour les petits objets (pour firefox aussi rapide pour les gros objets mais moyenne rapide sur les autres navigateurs)Détails
Des tests de performance ont été effectués pour
Les extraits ci-dessous présentent les solutions utilisées
Afficher l'extrait de code
Et voici le résultat pour les petits objets sur chrome
la source
Vous pouvez ajouter une fonction forEach simple à tous les objets, vous pouvez donc parcourir automatiquement n'importe quel objet:
Pour ceux qui n'aiment pas la méthode " for ... in ":
Maintenant, vous pouvez appeler simplement:
Si vous ne voulez pas avoir de conflits avec d'autres méthodes forEach, vous pouvez le nommer avec votre nom unique.
la source
Object
) est généralement considérée comme un anti motif car elle peut facilement provoquer des conflits avec d'autres codes. Donc, je ne recommande pas de le faire de cette façon.Les boucles peuvent être assez intéressantes lors de l'utilisation de JavaScript pur. Il semble que seul ECMA6 (nouvelle spécification JavaScript 2015) ait maîtrisé les boucles. Malheureusement, au moment où j'écris ceci, les navigateurs et l'environnement de développement intégré (IDE) populaire ont encore du mal à prendre en charge complètement les nouvelles cloches et sifflets.
En bref, voici à quoi ressemble une boucle d'objet JavaScript avant ECMA6:
De plus, je sais que cela est hors de portée avec cette question, mais en 2011, ECMAScript 5.1 a ajouté la
forEach
méthode pour les tableaux uniquement, ce qui a essentiellement créé une nouvelle façon améliorée de parcourir les tableaux tout en laissant des objets non itérables avec l'anciennefor
boucle verbeuse et déroutante . Mais la partie étrange est que cette nouvelleforEach
méthode ne prend pas en chargebreak
ce qui a conduit à toutes sortes d'autres problèmes.Fondamentalement, en 2011, il n'y a pas de véritable moyen solide de boucler en JavaScript autre que ce que de nombreuses bibliothèques populaires (jQuery, Underscore, etc.) ont décidé de réimplémenter.
Depuis 2015, nous avons maintenant une meilleure façon de boucler (et de casser) tout type d'objet (y compris les tableaux et les chaînes). Voici à quoi ressemblera finalement une boucle en JavaScript lorsque la recommandation deviendra grand public:
Notez que la plupart des navigateurs ne prendront pas en charge le code ci-dessus à partir du 18 juin 2016. Même dans Chrome, vous devez activer cet indicateur spécial pour qu'il fonctionne:
chrome://flags/#enable-javascript-harmony
Jusqu'à ce que cela devienne la nouvelle norme, l'ancienne méthode peut toujours être utilisée, mais il existe également des alternatives dans les bibliothèques populaires ou même des alternatives légères pour ceux qui n'utilisent aucune de ces bibliothèques.
la source
Uncaught TypeError: Object.entries is not a function
. N'est-il pas encore implémenté dans Chrome?Dans ES6, nous avons des symboles bien connus pour exposer certaines méthodes précédemment internes, vous pouvez l'utiliser pour définir le fonctionnement des itérateurs pour cet objet:
cela donnera le même résultat que l'utilisation de for ... dans la boucle es6.
Mais il est important de connaître les capacités que vous avez maintenant en utilisant es6!
la source
Object.keys()
et alloué en mémoire ... Cool!Je ferais cela plutôt que de vérifier
obj.hasOwnerProperty
dans chaquefor ... in
boucle.la source
la source
json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
Utiliser un
for-of
surObject.keys()
Comme:
la source
Si vous souhaitez également parcourir les propriétés non énumérables , vous pouvez utiliser
Object.getOwnPropertyNames(obj)
pour renvoyer un tableau de toutes les propriétés (énumérables ou non) trouvées directement sur un objet donné.la source
Error
objet et je ne pouvais pas accéder aux propriétés dans une boucle ou un_.forIn(err)
appel. L'utilisationObject.getOwnPropertyNames(err)
m'a permis d'accéder à toutes les parties duError
que je ne pouvais pas obtenir auparavant. Merci!Si quelqu'un doit parcourir les objets arrayObjects avec condition :
la source
Compte tenu de ES6, je voudrais ajouter ma propre cuillère de sucre et fournir une autre approche pour itérer sur les propriétés de l'objet.
Étant donné qu'un objet JS simple n'est pas itérable juste à la sortie de la boîte, nous ne pouvons pas utiliser la
for..of
boucle pour itérer sur son contenu. Mais personne ne peut nous empêcher de le rendre itérable .Ayons un
book
objet.Puisque nous l'avons fait, nous pouvons l'utiliser de cette façon:
Ou si vous connaissez la puissance des générateurs ES6 , vous pouvez certainement raccourcir le code ci-dessus.
Bien sûr, vous pouvez appliquer un tel comportement pour tous les objets en le rendant
Object
itérable auprototype
niveau.De plus, les objets conformes au protocole itérable peuvent être utilisés avec le nouvel opérateur d' étalement des fonctionnalités ES2015 , ce qui nous permet de lire les valeurs des propriétés des objets sous forme de tableau.
Ou vous pouvez utiliser l' affectation de déstructuration :
Vous pouvez consulter JSFiddle avec tout le code que j'ai fourni ci-dessus.
la source
depuis ES06, vous pouvez obtenir les valeurs d'un objet sous forme de tableau avec
il retourne un tableau des valeurs des objets et il n'extrait pas les valeurs du prototype !!
MDN DOCS Object.values ()
et pour les clés (déjà répondu devant moi ici)
la source
Dans le dernier script ES, vous pouvez faire quelque chose comme ceci:
la source