Come faccio a scorrere o enumerare un object JavaScript?

Ho un object JavaScript simile al seguente:

var p = { "p1": "value1", "p2": "value2", "p3": "value3" }; 

Ora voglio scorrere tutti gli elementi p ( p1 , p2 , p3 …) e ottenere le loro chiavi e valori. Come lo posso fare?

Posso modificare l’object JavaScript se necessario. Il mio objective finale è quello di scorrere alcune coppie di valori chiave e, se ansible, evitare di usare eval .

Puoi usare il ciclo for-in come mostrato da altri. Tuttavia, devi anche assicurarti che la chiave che ottieni sia una proprietà reale di un object e che non provenga dal prototipo.

Ecco il frammento:

 var p = { "p1": "value1", "p2": "value2", "p3": "value3" }; for (var key in p) { if (p.hasOwnProperty(key)) { console.log(key + " -> " + p[key]); } } 

Sotto ECMAScript 5, puoi combinare Object.keys() e Array.prototype.forEach() :

 var obj = { first: "John", last: "Doe" }; Object.keys(obj).forEach(function(key) { console.log(key, obj[key]); }); 

ES6 aggiunge for...of :

 for (const key of Object.keys(obj)) { console.log(key, obj[key]); } 

ES2017 aggiunge Object.entries() che evita di dover cercare ogni valore nell’object originale:

 Object.entries(obj).forEach( ([key, value]) => console.log(key, value) ); 

Sia Object.keys() che Object.entries() iterazione delle proprietà nello stesso ordine di for...in loop ma ignorano la catena del prototipo . Solo le proprietà enumerabili dell’object vengono iterate.

Modifica: ES2016 → ES6

Devi usare il ciclo for-in

Ma stai molto attento quando usi questo tipo di loop, perché questo farà un loop di tutte le proprietà lungo la catena del prototipo .

Pertanto, quando si utilizzano i cicli for-in, utilizzare sempre il metodo hasOwnProperty per determinare se la proprietà corrente hasOwnProperty è realmente una proprietà dell’object che si sta verificando:

 for (var prop in p) { if (!p.hasOwnProperty(prop)) { //The current property is not a direct property of p continue; } //Do your logic with the property here } 

La domanda non sarà completa se non menzioniamo i metodi alternativi per il looping degli oggetti.

Oggigiorno molte librerie JavaScript ben conosciute forniscono i propri metodi per iterare su raccolte, cioè su array , oggetti e oggetti tipo array . Questi metodi sono convenienti da usare e sono completamente compatibili con qualsiasi browser.

  1. Se lavori con jQuery , puoi usare il metodo jQuery.each() . Può essere usato per iterare senza interruzioni su entrambi gli oggetti e gli array:

     $.each(obj, function(key, value) { console.log(key, value); }); 
  2. In Underscore.js è ansible trovare il metodo _.each() , che scorre su un elenco di elementi, restituendo ciascuno a sua volta a una funzione fornita (prestare attenzione all’ordine degli argomenti nella funzione iteratee !):

     _.each(obj, function(value, key) { console.log(key, value); }); 
  3. Lo-Dash fornisce diversi metodi per iterare sulle proprietà dell’object. Basic _.forEach() (o il suo alias _.each() ) è utile per il looping tra oggetti e array, tuttavia (!) Gli oggetti con proprietà length sono trattati come array, e per evitare questo comportamento si consiglia di usare _.forIn() e _.forOwn() (anche questi hanno argomento value che viene prima):

     _.forIn(obj, function(value, key) { console.log(key, value); }); 

    _.forIn() iterazione delle proprie proprietà enumerabili ereditate di un object, mentre _.forOwn() iterazione solo sulle proprie proprietà di un object (fondamentalmente controllando la funzione hasOwnProperty ). Per oggetti semplici e letterali object qualsiasi di questi metodi funzionerà correttamente.

Generalmente tutti i metodi descritti hanno lo stesso comportamento con qualsiasi object fornito. Oltre a utilizzare il ciclo nativo for..in solito sarà più veloce di qualsiasi astrazione, come jQuery.each() , questi metodi sono notevolmente più facili da usare, richiedono meno codice e forniscono una migliore gestione degli errori.

In ECMAScript 5 hai un nuovo approccio nei campi di iterazione letterale – Object.keys

Maggiori informazioni che puoi vedere su MDN

Di seguito la mia scelta è una soluzione più rapida nelle versioni correnti dei browser (Chrome30, IE10, FF25)

 var keys = Object.keys(p), len = keys.length, i = 0, prop, value; while (i < len) { prop = keys[i]; value = p[prop]; i += 1; } 

Puoi confrontare le prestazioni di questo approccio con diverse implementazioni su jsperf.com :

  • Estendere le implementazioni
  • Iterazione delle chiavi dell'object
  • object letterale iterazione

Supporto del browser che puoi vedere sulla tavoletta di Kangax

Per il vecchio browser hai polyfill semplice e completo

UPD:

confronto delle prestazioni per tutti i casi più popolari in questa domanda su perfjs.info :

object letterale iterazione

Puoi semplicemente scorrere su di esso come:

 for (var key in p) { alert(p[key]); } 

Nota che la key non assumerà il valore della proprietà, è solo un valore di indice.

Poiché es2015 sta diventando sempre più popolare, sto postando questa risposta che include l’uso di generatore e iteratore per scorrere uniformsmente le coppie [key, value] . Come è ansible in altre lingue, ad esempio Ruby.

Ok ecco un codice:

 const MyObject = { 'a': 'Hello', 'b': 'it\'s', 'c': 'me', 'd': 'you', 'e': 'looking', 'f': 'for', [Symbol.iterator]: function* () { for (const i of Object.keys(this)) { yield [i, this[i]]; } } }; for (const [k, v] of MyObject) { console.log(`Here is key ${k} and here is value ${v}`); } 

Tutte le informazioni su come puoi fare un iteratore e un generatore che puoi trovare nella pagina Mozilla dello sviluppatore.

Spero che abbia aiutato qualcuno.

MODIFICARE:

ES2017 includerà Object.entries che renderà ancora più semplice l’iterazione delle coppie [key, value] negli oggetti. È ormai noto che farà parte di uno standard in base alle informazioni sullo stage ts39 .

Penso che sia ora di aggiornare la mia risposta per farla diventare ancora più fresca di adesso.

 const MyObject = { 'a': 'Hello', 'b': 'it\'s', 'c': 'me', 'd': 'you', 'e': 'looking', 'f': 'for', }; for (const [k, v] of Object.entries(MyObject)) { console.log(`Here is key ${k} and here is value ${v}`); } 

Puoi trovare ulteriori informazioni sull’utilizzo nella pagina MDN

tramite prototype con forEach () che dovrebbe saltare le proprietà della catena del prototipo :

 Object.prototype.each = function(f) { var obj = this Object.keys(obj).forEach( function(key) { f( key , obj[key] ) }); } //print all keys and values var obj = {a:1,b:2,c:3} obj.each(function(key,value) { console.log(key + " " + value) }); // a 1 // b 2 // c 3 

HasOwnProperty, dopo aver esaminato tutte le risposte, non è necessario per il mio utilizzo perché il mio object json è pulito; non ha davvero senso aggiungere ulteriori elaborazioni javascript. Questo è tutto ciò che sto usando:

 for (var key in p) { console.log(key + ' => ' + p[key]); // key is key // value is p[key] } 
 for(key in p) { alert( p[key] ); } 

Nota: è ansible farlo su array, ma si eseguirà l’iterazione anche sulla length e su altre proprietà.

È interessante Object.keys() in queste risposte le persone hanno toccato sia Object.keys() che for...of ma non le hanno mai combinate:

 var map = {well:'hello', there:'!'}; for (let key of Object.keys(map)) console.log(key + ':' + map[key]); 

Non puoi solo for...of un Object perché non è un iteratore, e for...index o .forEach() l’ Object.keys() è brutto / inefficiente.
Sono contento che la maggior parte della gente stia astenendosi da for...in (con o senza controllo .hasOwnProperty() ) visto che anche questo è un po ‘confuso, quindi oltre alla mia risposta sopra, sono qui per dire …


È ansible effettuare iterazioni ordinarie di oggetti iterate! Comportarsi come Map s con l’uso diretto della fantasia for...of
DEMO che funziona in Chrome e FF (presumo solo ES6)

 var ordinaryObject = {well:'hello', there:'!'}; for (let pair of ordinaryObject) //key:value console.log(pair[0] + ':' + pair[1]); //or for (let [key, value] of ordinaryObject) console.log(key + ':' + value); 

Finché includi il mio spessore sotto:

 //makes all objects iterable just like Maps!!! YAY //iterates over Object.keys() (which already ignores prototype chain for us) Object.prototype[Symbol.iterator] = function() { var keys = Object.keys(this)[Symbol.iterator](); var obj = this; var output; return {next:function() { if (!(output = keys.next()).done) output.value = [output.value, obj[output.value]]; return output; }}; }; 

Senza dover creare un vero object Map che non abbia il bel zucchero sintattico.

 var trueMap = new Map([['well', 'hello'], ['there', '!']]); for (let pair of trueMap) console.log(pair[0] + ':' + pair[1]); 

In effetti, con questo shim, se volevi ancora sfruttare le altre funzionalità di Map (senza shimming all in) ma volevi comunque utilizzare la notazione degli oggetti netti, dato che ora gli oggetti sono iterabili ora puoi semplicemente creare una Map da esso!

 //shown in demo var realMap = new Map({well:'hello', there:'!'}); 

Per coloro che non amano fare shim, o pasticciare con il prototype in generale, sentiti libero di creare la funzione sulla finestra, chiamandola qualcosa come getObjIterator() ;

 //no prototype manipulation function getObjIterator(obj) { //create a dummy object instead of adding functionality to all objects var iterator = new Object(); //give it what the shim does but as its own local property iterator[Symbol.iterator] = function() { var keys = Object.keys(obj)[Symbol.iterator](); var output; return {next:function() { if (!(output = keys.next()).done) output.value = [output.value, obj[output.value]]; return output; }}; }; return iterator; } 

Ora puoi chiamarlo semplicemente come una funzione ordinaria, nient’altro è influenzato

 var realMap = new Map(getObjIterator({well:'hello', there:'!'})) 

o

 for (let pair of getObjIterator(ordinaryObject)) 

Non c’è motivo per cui ciò non funzioni.

Benvenuto nel futuro.

Object.keys (obj): Array

recupera tutte le chiavi con valori stringa di tutte le proprietà enumerabili (non ereditate).

Quindi fornisce lo stesso elenco di chiavi che si intende testando ciascuna chiave dell’object con hasOwnProperty. Non hai bisogno di operazioni di test extra rispetto a Object.keys( obj ).forEach(function( key ){}) dovrebbe essere più veloce. Dimostriamolo:

 var uniqid = function(){ var text = "", i = 0, possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; for( ; i < 32; i++ ) { text += possible.charAt( Math.floor( Math.random() * possible.length ) ); } return text; }, CYCLES = 100000, obj = {}, p1, p2, p3, key; // Populate object with random properties Array.apply( null, Array( CYCLES ) ).forEach(function(){ obj[ uniqid() ] = new Date() }); // Approach #1 p1 = performance.now(); Object.keys( obj ).forEach(function( key ){ var waste = obj[ key ]; }); p2 = performance.now(); console.log( "Object.keys approach took " + (p2 - p1) + " milliseconds."); // Approach #2 for( key in obj ) { if ( obj.hasOwnProperty( key ) ) { var waste = obj[ key ]; } } p3 = performance.now(); console.log( "for...in/hasOwnProperty approach took " + (p3 - p2) + " milliseconds."); 

Prefazione:

  • Le proprietà dell’object possono essere proprie (la proprietà si trova sull’object stesso) o ereditate (non sull’object stesso, su uno dei suoi prototipi).
  • Le proprietà dell’object possono essere enumerabili o non enumerabili . Le proprietà non enumerabili sono escluse da molte enumerazioni / array di proprietà.
  • I nomi delle proprietà possono essere stringhe o simboli. Proprietà i cui nomi sono simboli vengono lasciati fuori da molte enumerazioni / array di proprietà.

Qui nel 2018, le opzioni per il looping delle proprietà di un object sono:

  1. for-in [ MDN , spec ] – Una struttura di loop che scorre i nomi delle proprietà enumerabili di un object, inclusi quelli ereditati, i cui nomi sono stringhe
  2. Object.keys [ MDN , spec ] – Una funzione che fornisce una matrice dei nomi delle proprietà enumerabili di un object i cui nomi sono stringhe.
  3. Object.values [ MDN , spec ] – Una funzione che fornisce una matrice dei valori delle proprietà enumerabili di un object.
  4. Object.entries [ MDN , spec ] – Una funzione che fornisce una matrice di nomi e valori delle proprietà enumerabili di un object.
  5. Object.getOwnPropertyNames [ MDN , spec ] – Una funzione che fornisce una matrice dei nomi delle proprietà di un object (anche non enumerabili) i cui nomi sono stringhe.
  6. Object.getOwnPropertySymbols [ MDN , spec ] – Una funzione che fornisce una matrice dei nomi delle proprietà di un object (anche non enumerabili) i cui nomi sono Simboli.
  7. Reflect.ownKeys [ MDN , spec ] – Una funzione che fornisce una matrice dei nomi delle proprietà di un object (anche non numerabili), se tali nomi sono stringhe o Simboli.
  8. Se si desidera che tutte le proprietà di un object, incluse quelle ereditate non enumerabili, sia necessario utilizzare un loop e Object.getPrototypeOf [ MDN , spec ] e utilizzare Object.getOwnPropertyNames , Object.getOwnPropertySymbols o Reflect.ownKeys su ciascun object nel catena prototipo (esempio in fondo a questa risposta).

Con tutti tranne for-in , dovresti usare una sorta di costrutto di loop sull’array ( for , for-of , forEach , ecc.).

Esempi:

for-in :

 // A prototype object to inherit from, with a string-named property const p = {answer: 42}; // The object we'll look at, which inherits from `p` const o = Object.create(p); // A string-named property o.question = "Life, the Universe, and Everything"; // A symbol-named property o[Symbol("author")] = "Douglas Adams"; for (const name in o) { const value = o[name]; console.log(`${name} = ${value}`); } 

Il metodo Object.keys() restituisce una matrice delle proprietà enumerabili di un dato object. Leggi di più qui

 var p = { "p1": "value1", "p2": "value2", "p3": "value3" }; Object.keys(p).map((key)=> console.log(key + "->" + p[key])) 

Ecco un altro metodo per iterare attraverso un object.

  var p = { "p1": "value1", "p2": "value2", "p3": "value3" }; Object.keys(p).forEach(key => { console.log(key, p[key]) }) 
 var p = { "p1": "value1", "p2": "value2", "p3": "value3" }; for (var key in p) { if (p.hasOwnProperty(key)) { console.log(key + " = " + p[key]); } } 
 

Output:
p1 = values1
p2 = values2
p3 = values3

È ansible aggiungere una semplice funzione forOach a tutti gli oggetti, in modo da poter scorrere automaticamente qualsiasi object:

 Object.defineProperty(Object.prototype, 'forEach', { value: function (func) { for (var key in this) { if (!this.hasOwnProperty(key)) { // skip loop if the property is from prototype continue; } var value = this[key]; func(key, value); } }, enumerable: false }); 

Per quelle persone a cui non piace il ” for … in ” -method:

 Object.defineProperty(Object.prototype, 'forEach', { value: function (func) { var arr = Object.keys(this); for (var i = 0; i < arr.length; i++) { var key = arr[i]; func(key, this[key]); } }, enumerable: false }); 

Ora puoi chiamare semplicemente:

 p.forEach (function(key, value){ console.log ("Key: " + key); console.log ("Value: " + value); }); 

Se non si desidera ottenere conflitti con altri metodi forEach, è ansible denominarlo con il proprio nome univoco.

Solo codice JavaScript senza dipendenze:

 var p = {"p1": "value1", "p2": "value2", "p3": "value3"}; keys = Object.keys(p); // ["p1", "p2", "p3"] for(i = 0; i < keys.length; i++){ console.log(keys[i] + "=" + p[keys[i]]); // p1=value1, p2=value2, p3=value3 } 

I loop possono essere piuttosto interessanti quando si utilizza JavaScript puro. Sembra che solo ECMA6 (Nuova specifica JavaScript 2015) abbia tenuto sotto controllo gli anelli. Sfortunatamente mentre sto scrivendo questo, sia i browser che il popolare ambiente di sviluppo integrato (IDE) stanno ancora lottando per supportare completamente i nuovi campanelli e fischietti.

A colpo d’occhio ecco come appare un loop di oggetti JavaScript prima di ECMA6:

 for (var key in object) { if (p.hasOwnProperty(key)) { var value = object[key]; console.log(key); // This is the key; console.log(value); // This is the value; } } 

Inoltre, so che questo argomento non rientra in questa domanda, ma nel 2011, ECMAScript 5.1 ha aggiunto il metodo forEach solo per gli Array, che fondamentalmente ha creato un nuovo modo migliorato di scorrere gli array lasciando ancora oggetti non iterabili con il vecchio loop dettagliato e confuso for . Ma la parte strana è che questo nuovo metodo forEach non supporta la break che ha portato a tutti i tipi di altri problemi.

Fondamentalmente, nel 2011, non esiste un vero e proprio modo per eseguire il loop in JavaScript diverso da quello che molte librerie popolari (jQuery, Underscore, ecc.) Hanno deciso di implementare nuovamente.

A partire dal 2015, ora abbiamo un modo migliore per eseguire il loop (e interrompere) qualsiasi tipo di object (inclusi Array e Stringhe). Ecco come apparirà un loop in JavaScript quando la raccomandazione diventerà mainstream:

 for (let [key, value] of Object.entries(object)) { console.log(key); // This is the key; console.log(value); // This is the value; } 

Tieni presente che la maggior parte dei browser non supporterà il codice sopra al 18 giugno 2016. Anche in Chrome devi abilitare questo flag speciale affinché funzioni: chrome://flags/#enable-javascript-harmony

Fino a quando questo non diventerà il nuovo standard, il vecchio metodo può ancora essere usato, ma ci sono anche alternative nelle librerie popolari o anche alternative leggere per coloro che non usano nessuna di queste librerie.

I would do this rather than checking obj.hasOwnerProperty within every for ... in loop.

 var obj = {a : 1}; for(var key in obj){ //obj.hasOwnProperty(key) is not needed. console.log(key); } //then check if anybody has messed the native object. Put this code at the end of the page. for(var key in Object){ throw new Error("Please don't extend the native object"); } 

If you want to iterate over non-enumerable properties as well, you can use Object.getOwnPropertyNames(obj) to return an array of all properties (enumerable or not) found directly upon a given object.

 var obj = Object.create({}, { // non-enumerable property getFoo: { value: function() { return this.foo; }, enumerable: false } }); obj.foo = 1; // enumerable property Object.getOwnPropertyNames(obj).forEach(function (name) { document.write(name + ': ' + obj[name] + '
'); });

Considering ES6 I’d like to add my own spoon of sugar and provide one more approach to iterate over object’s properties.

Since plain JS object isn’t iterable just out of box, we aren’t able to use for..of loop for iterating over its content. But no one can stop us to make it iterable .

Let’s we have book object.

 let book = { title: "Amazing book", author: "Me", pages: 3 } book[Symbol.iterator] = function(){ let properties = Object.keys(this); // returns an array with property names let counter = 0; let isDone = false; let next = () => { if(counter >= properties.length){ isDone = true; } return { done: isDone, value: this[properties[counter++]] } } return { next }; } 

Since we’ve made it we can use it this way:

 for(let pValue of book){ console.log(pValue); } ------------------------ Amazing book Me 3 

Or if you know the power of ES6 generators , so you certainly can make the code above much shorter.

 book[Symbol.iterator] = function *(){ let properties = Object.keys(this); for (let p of properties){ yield this[p]; } } 

Sure, you can apply such behavior for all objects with making Object iterable on prototype level.

 Object.prototype[Symbol.iterator] = function() {...} 

Also, objects that comply with the iterable protocol can be used with the new ES2015 feature spread operator thus we can read object property values as an array.

 let pValues = [...book]; console.log(pValues); ------------------------- ["Amazing book", "Me", 3] 

Or you can use destructuring assignment:

 let [title, , pages] = book; // notice that we can just skip unnecessary values console.log(title); console.log(pages); ------------------ Amazing book 3 

You can check out JSFiddle with all code I’ve provided above.

If anybody needs to loop through arrayObjects with condition :

 var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}]; for (var i=0; i< arrayObjects.length; i++) { console.log(arrayObjects[i]); for(key in arrayObjects[i]) { if (key == "status" && arrayObjects[i][key] == "good") { console.log(key + "->" + arrayObjects[i][key]); }else{ console.log("nothing found"); } } } 

In ES6 we have well-known symbols to expose some previously internal methods, you can use it to define how iterators work for this object:

 var p = { "p1": "value1", "p2": "value2", "p3": "value3", *[Symbol.iterator]() { yield *Object.keys(this); } }; [...p] //["p1", "p2", "p3"] 

this will give the same result as using for…in es6 loop.

 for(var key in p) { console.log(key); } 

But its important to know the capabilities you now have using es6!

An object becomes an iterator when it implements the .next() method

 const james = { name: 'James', height: `5'10"`, weight: 185, [Symbol.iterator]() { let properties = [] for (let key of Object.keys(james)){ properties.push(key); } index = 0; return { next: () => { let key = properties[index]; let value = this[key]; let done = index >= properties.length - 1 ; index++; return { key, value, done }; } }; } }; const iterator = james[Symbol.iterator](); console.log(iterator.next().value); // 'James' console.log(iterator.next().value); // `5'10` console.log(iterator.next().value); // 185 

If you want to iterate only over properties use one of the answers above, however if you want to iterate over everything including functions, then you might want to use Object.getOwnPropertyNames(obj)

 for (let o of Object.getOwnPropertyNames(Math)) { console.log(o); } 
  var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"}, {"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}] for(var value in p) { for (var key in value) { if (p.hasOwnProperty(key)) { console.log(key + " -> " + p[key]); } } } 

I had a similar problem when using Angular, here is the solution that I’ve found.

Step 1. Get all the object keys. using Object.keys. This method returns an array of a given object’s own enumerable properties.

Step 2. Create an empty array. This is an where all the properties are going to live, since your new ngFor loop is going to point to this array, we gotta catch them all. Step 3. Iterate throw all keys, and push each one into the array you created. Here’s how that looks like in code.

  // Evil response in a variable. Here are all my vehicles. let evilResponse = { "car" : { "color" : "red", "model" : "2013" }, "motorcycle": { "color" : "red", "model" : "2016" }, "bicycle": { "color" : "red", "model" : "2011" } } // Step 1. Get all the object keys. let evilResponseProps = Object.keys(evilResponse); // Step 2. Create an empty array. let goodResponse = []; // Step 3. Iterate throw all keys. for (prop of evilResponseProps) { goodResponse.push(evilResponseProps[prop]); } 

Here is a link to the original post. https://medium.com/@papaponmx/looping-over-object-properties-with-ngfor-in-angular-869cd7b2ddcc

since ES06 you can get the values of an object as array with

 let arrValues = Object.values( yourObject) ; 

it return the an array of the object values and it not extract values from Prototype!!

MDN DOCS Object.values()

and for keys ( allready answerd before me here )

 let arrKeys = Object.keys(yourObject); 
  • single level indent
  • single set of brackets
  • highest browser compatibility
  • hasOwnProperty safe
 var p = {"p1": "value1", "p2": "value2", "p3": "value3"}; for (var key in p) if (p.hasOwnProperty(key)) { var value = p[key]; console.log(key, value); }