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


455

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 de propriété (c'est-à-dire sans connaître les «clés»), comment obtenir chaque valeur de propriété dans une boucle?


23
Note aux lecteurs: ne manquez pas la deuxième réponse
Pandaiolo

Réponses:


447

En utilisant une for..inboucle simple :

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

90
Faites attention aux propriétés de l'objet prototype hérité. Voir: hasOwnProperty ()
olive

102
Si vous lisez cette réponse, vous devriez certainement lire l'autre
mgarciaisaia

18
Si vous lisez cette réponse et que vous avez peut-être affaire à des chaînes, vous devez certainement pointer javascript au visage.

Si vous lisez la réponse ci-dessus et que vous voulez frapper JavaScript au visage, essayez lodash
slugmandrew

Doit probablement signaler que cela n'inclura PAS les propriétés dont l' enumerableindicateur est défini sur false. Cela - entre autres - signifie que vous n'itérerez pas sur les méthodes de classe, mais que vous itérerez sur les méthodes créées d'autres manières.
remer riche

1012

Selon les navigateurs que vous devez prendre en charge, cela peut se faire de plusieurs manières. La grande majorité des navigateurs dans la nature prennent en charge ECMAScript 5 (ES5), mais sachez que la plupart des exemples ci-dessous utilisent Object.keys, qui n'est pas disponible dans IE <9. Voir le tableau de compatibilité .

ECMAScript 3+

Si vous devez prendre en charge les anciennes versions d'IE, alors c'est l'option pour vous:

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

L'imbriqué ifs'assure que vous n'énumérez pas les propriétés dans la chaîne prototype de l'objet (ce qui est le comportement que vous voulez 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 ces objets n'auront pas la hasOwnPropertyméthode. Le code vilain peut également produire des objets qui remplacent la hasOwnPropertyméthode.

ECMAScript 5+

Vous pouvez utiliser ces méthodes dans n'importe quel navigateur prenant en charge ECMAScript 5 et supérieur. Ceux-ci obtiennent des valeurs d'un objet et évitent d'énumérer sur la chaîne de prototype. Où objest 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 en boucle, alors Array.prototype.forEachvotre ami est:

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 boucler.

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

// use vals array

Si vous voulez faire ceux qui utilisent Object.keyscontre la sécurité null(comme for-inest), alors vous pouvez le faire Object.keys(obj || {})....

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

ECMAScript 2015+ (AKA ES6)

Les tableaux sont plus faciles à itérer avec ECMAScript 2015. Vous pouvez l'utiliser à 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
}

À l'aide des fonctions de flèche grasse d'ECMAScript 2015, le mappage de l'objet à un tableau de valeurs devient une ligne unique:

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

// use vals array

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

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

Les compréhensions des tableaux ont été supprimées d'ECMAScript 6 avant la 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.valueset Object.entries. Les deux tableaux de retour (ce qui sera surprenant pour certains étant donné l'analogie avec Array.entries). Object.valuespeut être utilisé tel quel ou avec une for-ofboucle.

const values = Object.values(obj);

// use values array or:

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

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

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 peut être utile d'utiliser l'un d'entre eux comme une cale. Ne vous inquiétez pas, ce qui suit ne change pas le prototype, il ajoute simplement une méthode à Object(ce qui est beaucoup moins dangereux). En utilisant les fonctions de flèche grasse, cela peut également ê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 lorsqu'un natif Object.valuesexiste, 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 du langage sont implémentées. Par exemple, la prise en charge d'ECMAScript 2015 a été désactivée par défaut dans V8 jusqu'à récemment, ce qui alimentait des navigateurs tels que Chrome. Les fonctionnalités d'ECMAScript 2015 doivent être évitées jusqu'à ce que les navigateurs que vous envisagez de prendre en charge implémentent les fonctionnalités dont vous avez besoin. Si vous utilisez babel pour compiler votre code vers ECMAScript 5, vous avez alors accès à toutes les fonctionnalités de cette réponse.


9
Ce devrait être la réponse acceptée (ou au moins la plus appréciée) car celle acceptée est incomplète (@olive le souligne).
0xc0de

C'est dommage que de tous les soi-disant trucs, nous devons encore mentionner objdeux fois. Je suppose que la création d'une fonction d'aide est inévitable? Quelque chose comme des valeurs (obj).
Steven Haryanto

N'importe laquelle de ces méthodes peut être utilisée comme une cale. Par exemple:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte

1
Les solutions ECMA 5 devraient fonctionner dans tous les navigateurs modernes. ECMA 6 n'est pas encore finalisé et le support est préliminaire dans tous les navigateurs. Dans Chrome, ECMA 6 est partiellement implémenté mais désactivé. Dans Firefox, le support est meilleur mais la compréhension du tableau est erronée (comme mentionné). Je pensais que mon utilisation du futur impliquerait cela. @JacekLampart, quelle solution vous a donné l'erreur?
qubyte

2
Je ne peux pas imaginer pourquoi nous devons attendre ES2017 pour obtenir une méthode Object.values ​​().
Herbertusz

31

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;
}

15
La modification Objectn'est pas vraiment un problème ( Object.keysc'est une cale courante), vous songez probablement à modifier le prototype Object.
sandstrom

Pourquoi auriez-vous besoin de tester avec hasOwnProperty()? Comment la clé serait-elle itérée dans la boucle de cet objet qui n'a pas la propriété?
1252748

4
Google it @thomas, c'est important. Il pourrait avoir des propriétés de sa chaîne de prototypes.
Joe

28

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

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

@MathieuAmiot - vous voulez expliquer?
Paden

lodash est un remplacement compatible api du trait de soulignement, un moyen (beaucoup plus rapide).
Mathieu Amiot

@Paden voici une question connexe sur SO: stackoverflow.com/questions/13789618/…
jichi

2
lodash n'est pas nécessaire pour cela et va gonfler votre base de code
dman

14

Si vous voulez vraiment un tableau de valeurs, je trouve cela plus propre 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 convient de 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]);

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


9

ES5 Object.keys

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

3
Pourquoi cela a-t-il été déclassé? Je dirais que c'est l'une des solutions les plus propres.
Sebastian Hojas

Je ne sais pas, pourquoi ce vote est-il rejeté. C'est la solution la plus simple et la plus pure de js sans utiliser de bibliothèques ou d'autres utilitaires.
sanjeev shetty

5

Vous pouvez parcourir les clés:

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

2
Vous devez également vérifier `hasOwnProperty () 'si vous voulez éviter les attributs hérités.
0xc0de

3

Pour les premiers à s'adapter à l'ère CofeeScript, voici un autre équivalent.

val for key,val of objects

Ce qui peut être mieux que cela, car le objectspeut être réduit pour être tapé à nouveau et la lisibilité diminuée.

objects[key] for key of objects

3

utiliser un polyfill comme:

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

puis utilisez

Object.values(my_object)

3) profit!



2

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]];
}

pouvez-vous mettre un codepen ou jsfiddle d'un exemple de cela? Merci.
Chris22

2

La question ne précise pas si vous souhaitez également des propriétés héritées et non énumérables.

Il y a une question pour obtenir tout, les propriétés héritées et les propriétés non énumérables , que Google ne peut pas facilement trouver.

Ma solution pour cela est:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

Et puis parcourez-les, utilisez simplement une boucle for-of:


1

Utilisez:, Object.values()nous passons un objet comme argument et recevons un tableau de valeurs comme valeur de retour.

Cela retourne un tableau d'un objet donné propres valeurs de propriété énumérables. Vous obtiendrez les mêmes valeurs qu'en utilisant la for inboucle mais sans les propriétés sur le prototype. Cet exemple clarifiera probablement les choses:

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
const object1 = {
  a: 'somestring',
  b: 42
};

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed

0

Voici une fonction similaire à PHP array_values ​​()

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 supérieur:

Array.from(values(obj));

Pour certaines raisons, values ​​() fonctionne dans Chrome et Firefox, mais pas sur iojs / node.
jaggedsoft

0

Compatible avec ES7, même certains navigateurs ne le prennent pas encore en charge

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

Jusqu'à ce que tous les navigateurs l'attendent, vous pouvez l'envelopper dans une fonction:

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

Alors :

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

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


0

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

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

0

Les entrées d'objet le font mieux.

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


0

const myObj = { a:1, b:2, c:3 }

Obtenez toutes les valeurs:

  • le chemin le plus court:

    • const myValues = Object.values(myObj)
  • const myValues = Object.keys(myObj).map(key => myObj[key])


-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }

-5

dans l' utilisation d' ECMAScript5

 keys = Object.keys(object);

Sinon, si votre navigateur ne le prend pas en charge, utilisez le for..in loop

for (key in object) {
    // your code here
}

17
La question demandait les valeurs, pas les clés.
zachelrath

@zachelrath Vous avez raison. - Mais ce script est utile si vous voulez obtenir les valeurs parce que lorsque vous connaissez les clés, vous pouvez utiliser object[key]pour obtenir les valeurs dans une boucle.
fridojet

2
@fridojet Mais cela peut être fait avec for..in(et hasOwnProperty) donc ça ne gagne vraiment rien. Je souhaite que ECMAScript 5ème soit défini Object.pairs(et Object.itemspour [[key, value], ..]), mais hélas, ce n'est pas le cas.
user2246674

-8

J'utilise maintenant Dojo Toolkit car les anciens navigateurs ne le prennent pas en charge Object.values.

require(['dojox/lang/functional/object'], function(Object) {
    var obj = { key1: '1', key2: '2', key3: '3' };
    var values = Object.values(obj);
    console.log(values);
});

Production :

['1', '2', '3']

5
À strictement parler, le tableau n'est pas correct. Vous avez un tableau de chaînes au lieu d'un tableau de nombres.
qubyte

-10

utilisation

console.log(variable)

et si vous utilisez google chrome open Console en utilisant Ctrl + Maj + j

Aller >> Console

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.