web-dev-qa-db-fra.com

Comment obtenir toutes les valeurs de propriétés d'un objet Javascript (sans connaître les clés)?

S'il y a un objet Javascript:

var objects={...};

Supposons qu'il possède plus de 50 propriétés, sans connaître les noms des propriétés (c'est-à-dire sans connaître les "clés"), comment obtenir chaque valeur de propriété dans une boucle?

431
Mellon

En utilisant une simple boucle for..in:

for(var key in objects) {
    var value = objects[key];
}
424
Tatu Ulmanen

Selon les navigateurs que vous devez prendre en charge, cela peut être fait de différentes manières. L'écrasante majorité des navigateurs dans la nature supporte ECMAScript 5 (ES5), mais sachez que de nombreux exemples ci-dessous utilisent Object.keys, qui n'est pas disponible dans IE <9. Voir les - tableau de compatibilité .

ECMAScript 3+

Si vous devez prendre en charge les anciennes versions d'Internet Explorer, cette option vous convient:

for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        var val = obj[key];
        // use val
    }
}

Le if imbriqué veille à ne pas énumérer les propriétés de la chaîne de prototypes de l'objet (comportement que vous souhaiterez presque certainement). Tu dois utiliser

Object.prototype.hasOwnProperty.call(obj, key) // ok

plutôt que

obj.hasOwnProperty(key) // bad

car ECMAScript 5+ vous permet de créer des objets sans prototype avec Object.create(null), et que ces objets n'auront pas la méthode hasOwnProperty. Le code vilain peut également produire des objets qui surchargent la méthode hasOwnProperty.

ECMAScript 5+

Vous pouvez utiliser ces méthodes dans tout navigateur prenant en charge ECMAScript 5 et versions ultérieures. Ceux-ci obtiennent des valeurs d'un objet et évitent d'énumérer sur la chaîne de prototypes. Où obj est votre objet:

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]];
    // use val
}

Si vous voulez quelque chose d'un peu plus compact ou si vous voulez faire attention aux fonctions dans les boucles, alors Array.prototype.forEach est votre ami:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});

La méthode suivante construit un tableau contenant les valeurs d'un objet. C'est pratique pour faire une boucle.

var vals = Object.keys(obj).map(function (key) {
    return obj[key];
});

// use vals array

Si vous voulez protéger ceux qui utilisent Object.keys contre null (comme for-in est), vous pouvez alors utiliser Object.keys(obj || {})....

Object.keys renvoie propriétés énumérables . Pour itérer sur des objets simples, cela suffit généralement. Si vous devez travailler avec quelque chose avec des propriétés non énumérables, vous pouvez utiliser Object.getOwnPropertyNames à la place de Object.keys.

ECMAScript 2015+ (A.K.A. ES6)

Il est plus facile d'itérer des tableaux avec ECMAScript 2015. Vous pouvez utiliser ceci à votre avantage lorsque vous travaillez avec des valeurs une par une dans une boucle:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

Avec les fonctions ECMAScript 2015 fat-arrow, le mappage de l'objet sur un tableau de valeurs devient un élément linéaire:

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array

ECMAScript 2015 introduit Symbol, dont les instances peuvent être utilisées en tant que noms de propriétés. Pour obtenir l'énumération des symboles d'un objet, utilisez Object.getOwnPropertySymbols (cette fonction explique pourquoi Symbol ne peut pas être utilisé pour créer des propriétés privées). La nouvelle API Reflect d'ECMAScript 2015 fournit Reflect.ownKeys, qui renvoie une liste de noms de propriétés (y compris ceux non énumérables) et de symboles.

Compréhensions du tableau (n'essayez pas de les utiliser)

Les compréhensions de tableau ont été supprimées d'ECMAScript 6 avant publication. Avant leur suppression, une solution aurait ressemblé à:

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array

ECMAScript 2017+

ECMAScript 2016 ajoute des fonctionnalités qui n'ont pas d'impact sur ce sujet. La spécification ECMAScript 2017 ajoute Object.values et Object.entries. Les deux retournent des tableaux (ce qui surprendra certains, étant donné l'analogie avec Array.entries). Object.values peut être utilisé tel quel ou avec une boucle for-of.

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}

Si vous voulez utiliser à la fois la clé et la valeur, alors Object.entries est pour vous. Il produit un tableau rempli de [key, value] paires. Vous pouvez utiliser ceci tel quel, ou (notez également l'affectation de déstructuration ECMAScript 2015) dans une boucle for-of:

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}

Object.values cale

Enfin, comme indiqué dans les commentaires et par teh_senaus dans une autre réponse, il pourrait être utile d’utiliser l’un d’eux comme solution de rechange. Ne vous inquiétez pas, ce qui suit ne change pas le prototype, il ajoute simplement une méthode à Object (qui est beaucoup moins dangereux). En utilisant les fonctions Fat-Arrow, cela peut aussi être fait sur une seule ligne:

Object.values = obj => Object.keys(obj).map(key => obj[key]);

que vous pouvez maintenant utiliser comme

// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });

Si vous voulez éviter le calage quand un Object.values natif existe, alors vous pouvez faire:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));

Finalement...

Soyez conscient des navigateurs/versions que vous devez prendre en charge. Les éléments ci-dessus sont corrects lorsque les méthodes ou les fonctionnalités de langage sont implémentées. Par exemple, la prise en charge d'ECMAScript 2015 était désactivée par défaut dans la version 8 jusqu'à récemment, ce qui permettait aux navigateurs tels que Chrome. Les fonctionnalités d'ECMAScript 2015 doivent être évitées jusqu'à ce que les navigateurs que vous avez l'intention de prendre en charge implémentent les fonctionnalités dont vous avez besoin. Si vous utilisez babel pour compiler votre code dans ECMAScript 5, vous avez accès à toutes les fonctionnalités de cette réponse.

972
qubyte

Voici une fonction réutilisable pour obtenir les valeurs dans un tableau. Il prend également en compte les prototypes.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.Push(obj[key]);
        }
    }
    return vals;
}
30
teh_senaus

Si vous avez accès à Underscore.js, vous pouvez utiliser la fonction _.values comme ceci:

__.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]
_
28
jichi

Si vous voulez vraiment un tableau de valeurs, je trouve cela plus simple que de construire un tableau avec une boucle for ... in.

ECMA 5.1+

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }

Il est à noter que dans la plupart des cas, vous n'avez pas vraiment besoin d'un tableau de valeurs, il sera plus rapide de le faire:

for(var k in o) something(o[k]);

Ceci itère sur les clés de l'objet o. Dans chaque itération, k est défini sur une clé de o.

14
zzz

ES5 Object.keys

_var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]
_
9
MrBii

Vous pouvez parcourir les touches:

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}

affichera:

foo[one]=1
foo[two]=2
foo[three]=3
5
ariera

utilisez un polyfill comme:

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

puis utiliser

Object.values(my_object)

3) profit!

3
user40521

Pour ceux qui s’adaptent très tôt à l’ère CofeeScript, voici un autre équivalent.

val for key,val of objects

Ce qui peut être meilleur que cela parce que la objects peut être réduite pour être tapée à nouveau et une lisibilité réduite.

objects[key] for key of objects
3
Ch.Idea

Apparemment, comme je l’ai récemment appris, c’est le moyen le plus rapide de le faire:

var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
    // do whatever in here
    var obj = objs[objKeys[i]];
}
2
dylnmc

ECMA2017 et suivants:

Object.values(obj) vous récupérera toutes les valeurs de propriétés sous forme de tableau.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

2
ishandutta2007

Use: Object.values(), nous passons un objet en argument et recevons un tableau des valeurs en tant que valeur de retour.

Cela retourne un tableau de valeurs de propriétés énumérables propres à un objet donné. Vous obtiendrez les mêmes valeurs qu'en utilisant la boucle for in mais sans les propriétés du prototype. Cet exemple rendra probablement les choses plus claires:

function person (name) {
  this.name = name;
}

person.prototype.age = 5;

let dude = new person('dude');

for(let prop in dude) {
  console.log(dude[prop]);     // for in still shows age because this is on the prototype
}                              // we can use hasOwnProperty but this is not very elegant

// ES6 + 
console.log(Object.values(dude));
// very concise and we don't show props on prototype
1
Willem van der Veen

Je me rends compte que je suis un peu en retard mais voici une shim pour la nouvelle méthode firefox 47 Object.values

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};
0
Jamie

Object.entries le fait mieux.

  var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
 
   Object.entries(dataObject).map(itemArray => { 
     console.log("key=", itemArray[0], "value=", itemArray[1])
  })
0
Asif J

Voici une fonction similaire à array_values ​​() de PHP

function array_values(input) {
  var output = [], key = '';
  for ( key in input ) { output[output.length] = input[key]; }
  return output;
}

Voici comment obtenir les valeurs de l'objet si vous utilisez ES6 ou une version ultérieure:

Array.from(values(obj));
0
jaggedsoft

Compatible avec ES7 même certains navigateurs ne le supportent pas encore

Depuis, Object.values(<object>) sera intégré ES7 &

En attendant que tous les navigateurs le prennent en charge, vous pouvez l’envelopper dans une fonction:

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

Ensuite :

Object.vals({lastname:'T',firstname:'A'})
 // ['T','A']

Une fois que les navigateurs sont compatibles avec ES7, vous n’aurez plus rien à changer dans votre code.

0
Abdennour TOUMI