Come ottenere tutti i valori delle proprietà di un oggetto JavaScript (senza conoscere le chiavi)?


Risposte:


447

Utilizzando un semplice for..inciclo:

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

90
Prestare attenzione alle proprietà dell'oggetto prototipo che viene ereditato. Vedi: hasOwnProperty ()
olive

102
Se stai leggendo questa risposta, dovresti assolutamente leggere l'altro
Margarciaisaia,

18
Se stai leggendo questa risposta e potresti avere a che fare con le stringhe, dovresti sicuramente dare un pugno a javascript in faccia.

Se leggi la risposta sopra e vuoi dare un pugno JavaScript in faccia, prova a lodash
slugmandrew,

Probabilmente dovresti sottolineare che questo NON includerà proprietà che hanno il loro enumerableflag impostato su false. Questo - tra le altre cose - significa che non ripeterai i metodi di classe, ma ripeterai i metodi creati in altri modi.
rich remer

1012

A seconda di quali browser devi supportare, questo può essere fatto in diversi modi. La stragrande maggioranza dei browser nel selvaggio supporta ECMAScript 5 (ES5), ma attenzione che molti degli esempi seguenti usano Object.keys, che non è disponibile in IE <9. Vedi la tabella di compatibilità .

ECMAScript 3+

Se devi supportare versioni precedenti di IE, questa è l'opzione che fa per te:

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

Il nidificato iffa in modo di non enumerare le proprietà nella catena di prototipi dell'oggetto (che è il comportamento che quasi sicuramente desideri). Devi usare

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

piuttosto che

obj.hasOwnProperty(key) // bad

perché ECMAScript 5+ ti consente di creare oggetti senza prototipo Object.create(null)e questi oggetti non avranno il hasOwnPropertymetodo. Il codice cattivo potrebbe anche produrre oggetti che sovrascrivono il hasOwnPropertymetodo.

ECMAScript 5+

È possibile utilizzare questi metodi in qualsiasi browser che supporti ECMAScript 5 e versioni successive. Questi ottengono valori da un oggetto ed evitano di enumerare la catena di prototipi. Dov'è il objtuo oggetto:

var keys = Object.keys(obj);

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

Se vuoi qualcosa di un po 'più compatto o vuoi stare attento con le funzioni nei loop, allora Array.prototype.forEachè tuo amico:

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

Il metodo successivo crea un array contenente i valori di un oggetto. Questo è comodo per il looping.

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

// use vals array

Se vuoi rendere Object.keyssicuri quelli che usano contro null(così com'è for-in), allora puoi farlo Object.keys(obj || {})....

Object.keysrestituisce proprietà enumerabili . Per iterare su oggetti semplici, questo di solito è sufficiente. Se hai qualcosa con proprietà non enumerabili con cui devi lavorare, puoi usare Object.getOwnPropertyNamesal posto di Object.keys.

ECMAScript 2015+ (AKA ES6)

Le matrici sono più facili da ripetere con ECMAScript 2015. Puoi utilizzarlo a tuo vantaggio quando lavori con i valori uno a uno in un ciclo:

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

Utilizzando le funzioni fat-arrow di ECMAScript 2015, la mappatura dell'oggetto su una matrice di valori diventa una riga:

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

// use vals array

ECMAScript 2015 introduce Symbol, le cui istanze possono essere utilizzate come nomi di proprietà. Per ottenere i simboli di un oggetto da enumerare, utilizzare Object.getOwnPropertySymbols(questa funzione è il motivo per cui Symbol non può essere utilizzata per creare proprietà private). ReflectFornisce la nuova API di ECMAScript 2015 Reflect.ownKeys, che restituisce un elenco di nomi di proprietà (compresi quelli non enumerabili) e simboli.

Comprensioni dell'array (non tentare di utilizzare)

Le comprensioni dell'array sono state rimosse da ECMAScript 6 prima della pubblicazione. Prima della loro rimozione, una soluzione sarebbe stata simile a:

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

// use vals array

ECMAScript 2017+

ECMAScript 2016 aggiunge funzionalità che non incidono su questo argomento. La specifica ECMAScript 2017 aggiunge Object.valuese Object.entries. Entrambi restituiscono gli array (il che sarà sorprendente per alcuni data l'analogia con Array.entries). Object.valuespuò essere usato così com'è o con un for-ofciclo.

const values = Object.values(obj);

// use values array or:

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

Se vuoi usare sia la chiave che il valore, allora Object.entriesè per te. Produce una matrice piena di [key, value]coppie. Puoi usarlo così com'è, oppure (nota anche il compito di destrutturazione di ECMAScript 2015) in un for-ofciclo:

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

Object.values shim

Infine, come notato nei commenti e da teh_senaus in un'altra risposta, può valere la pena usarne uno come shim. Non preoccuparti, il seguente non modifica il prototipo, ma aggiunge semplicemente un metodo Object(che è molto meno pericoloso). Usando le funzioni fat-arrow, questo può essere fatto anche in una riga:

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

che ora puoi usare come

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

Se vuoi evitare lo shimmer quando Object.valuesesiste un nativo , puoi fare:

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

Finalmente...

Sii consapevole dei browser / versioni che devi supportare. Quanto sopra è corretto dove sono implementati i metodi o le funzionalità del linguaggio. Ad esempio, il supporto per ECMAScript 2015 è stato disattivato per impostazione predefinita in V8 fino a poco tempo fa, che alimentava browser come Chrome. Le funzionalità di ECMAScript 2015 devono essere evitate fino a quando i browser che si intende supportare implementano le funzionalità necessarie. Se usi babel per compilare il tuo codice in ECMAScript 5, hai accesso a tutte le funzionalità di questa risposta.


9
Questa dovrebbe essere la risposta accettata (o almeno più votata) in quanto quella accettata è incompleta (@olive lo sottolinea).
0xc0de,

È un peccato che di tutti i cosiddetti trucchi, dobbiamo ancora menzionarlo objdue volte. Immagino che la creazione di una funzione di supporto sia inevitabile? Qualcosa di simile ai valori (obj).
Steven Haryanto,

Ognuno di questi metodi può essere usato come spessore. Ad esempio:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte

1
Le soluzioni ECMA 5 dovrebbero funzionare in tutti i browser moderni. ECMA 6 non è stato ancora finalizzato e il supporto è preliminare in tutti i browser. In Chrome, ECMA 6 è parzialmente implementato ma disabilitato. In Firefox, il supporto è migliore ma la comprensione dell'array è errata (come detto). Pensavo che il mio uso del tempo futuro avrebbe implicato questo. @JacekLampart, quale soluzione ti ha dato l'errore?
qubyte

2
Non riesco a immaginare perché dobbiamo aspettare che ES2017 ottenga un metodo Object.values ​​().
Herbertusz,

31

Ecco una funzione riutilizzabile per ottenere i valori in un array. Prende in considerazione anche i prototipi.

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

15
La modifica Objectnon è un grosso problema ( Object.keysè uno shim comune), probabilmente stai pensando di modificare il prototipo Object.
sandstrom,

Perché dovresti provare con hasOwnProperty()? In che modo la chiave sarebbe ripetuta all'interno del ciclo di quell'oggetto non ha la proprietà?
1252748

4
Google it @thomas, è importante. Potrebbe avere proprietà dalla sua catena di prototipi.
Joe,

28

Se hai accesso a Underscore.js, puoi utilizzare la _.valuesfunzione in questo modo:

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

@MathieuAmiot - ti interessa spiegare?
Paden,

lodash è un sostituto compatibile con api per il carattere di sottolineatura, uno (molto più veloce).
Mathieu Amiot,

@Paden ecco una domanda correlata su SO: stackoverflow.com/questions/13789618/…
jichi

2
lodash non è necessario per questo e gonfia la tua base di codice
dman

14

Se vuoi davvero un array di valori, lo trovo più pulito rispetto alla creazione di un array con un ciclo for ... in.

ECMA 5.1+

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

Vale la pena notare che nella maggior parte dei casi non è davvero necessario un array di valori, sarà più veloce farlo:

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

Ciò scorre sulle chiavi dell'oggetto o. In ogni iterazione k è impostato su una chiave di 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
Perché questo è stato sottoposto a downgrade? Direi che questa è una delle soluzioni più pulite.
Sebastian Hojas,

Non lo so, perché questo è votato verso il basso. Questa è la soluzione più semplice e pura in js senza usare alcuna libreria o altra utilità.
sanjeev shetty,

5

Puoi scorrere tra i tasti:

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

produrrà:

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

2
Devi anche selezionare `hasOwnProperty () 'se vuoi evitare gli attributi ereditati.
0xc0de,

3

Per quelle persone che si adeguano presto all'era di CofeeScript, ecco un altro equivalente per questo.

val for key,val of objects

Quale potrebbe essere migliore di questo perché objectspuò essere ridotto per essere nuovamente digitato e ridotta leggibilità.

objects[key] for key of objects

3

usa un polyfill come:

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

quindi utilizzare

Object.values(my_object)

3) profitto!



2

Apparentemente - come ho appreso di recente - questo è il modo più veloce per farlo:

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

puoi mettere un codepen o jsfiddle di un esempio di questo? Grazie.
Chris22

2

La domanda non specifica se si desidera anche proprietà ereditate e non enumerabili.

C'è una domanda per ottenere tutto, proprietà ereditate e anche proprietà non enumerabili , che Google non riesce a trovare facilmente.

La mia soluzione per questo è:

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

E quindi scorrere su di essi, basta usare un ciclo for-of:


1

Usa Object.values():, passiamo un oggetto come argomento e riceviamo una matrice di valori come valore di ritorno.

Ciò restituisce una matrice di valori di proprietà enumerabili propri di un determinato oggetto. Otterrai gli stessi valori utilizzando il for inciclo ma senza le proprietà sul prototipo. Questo esempio probabilmente renderà le cose più chiare:

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

Ecco una funzione simile a array_values ​​() di PHP

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

Ecco come ottenere i valori dell'oggetto se si utilizza ES6 o versione successiva:

Array.from(values(obj));

Per qualche ragione i valori () funziona su Chrome e Firefox, ma non su iojs / node.
jaggedsoft,

0

Compatibile con ES7 anche alcuni browser non lo supportano ancora

Da allora, Object.values(<object>)sarà integrato in ES7 e

Fino ad attendere che tutti i browser lo supportino, è possibile inserirlo in una funzione:

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

Poi :

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

Una volta che i browser diventano compatibili con ES7, non dovrai cambiare nulla nel tuo codice.


0

Mi rendo conto di essere un po 'in ritardo, ma ecco uno spessore per il nuovo Object.valuesmetodo Firefox 47

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

0

Object.entries lo fa in modo migliore.

  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 }

Ottieni tutti i valori:

  • il modo più breve:

    • 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

in ECMAScript5 uso

 keys = Object.keys(object);

Altrimenti se il tuo browser non lo supporta, usa il noto for..in loop

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

17
La domanda era chiedere i valori, non le chiavi.
Zachelrath,

@zachelrath Hai ragione. - Ma questo script è utile se vuoi ottenere i valori perché quando conosci le chiavi puoi usare object[key]per ottenere i valori in un ciclo.
fridojet,

2
@fridojet Ma questo può essere fatto con for..in(e hasOwnProperty) in modo che non ottenga davvero nulla .. Vorrei che ECMAScript 5th fosse definito Object.pairs(e Object.itemsper [[key, value], ..]), ma purtroppo non lo è.
user2246674

-8

Ora uso Dojo Toolkit perché i browser più vecchi non supportano 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);
});

Produzione :

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

5
A rigor di termini, l'array non è corretto. Hai una matrice di stringhe anziché una matrice di numeri.
qubyte

-10

uso

console.log(variable)

e se usi google chrome apri la Console usando Ctrl + Maiusc + j

Vai a >> Console

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.