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?

Mellon
la source
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];
}
Tatu Ulmanen
la source
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.

qubyte
la source
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;
}
teh_senaus
la source
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]
jichi
la source
@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.

zzz
la source
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]
MrBii
la source
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
ariera
la source
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
Ch.Idea
la source
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!

user40521
la source
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]];
}
dylnmc
la source
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:

non-polarité
la source
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

Willem van der Veen
la source
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
priya_21
la source
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));
jaggedsoft
la source
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.

Abdennour TOUMI
la source
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];
  });
};
Jamie
la source
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])
  })

Mustkeem K
la source
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])

Anatoliy_Z
la source
-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }
Sudarshan
la source
-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
}
user278064
la source
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']
Rio
la source
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

Puneet
la source