Hoe een gewoon JavaScript-object doorlopen met de objecten als leden

Hoe kan ik alle leden in een JavaScript-object doorlopen, inclusief waarden die objecten zijn?

Hoe kan ik dit bijvoorbeeld doorlopen (toegang tot de “your_name” en “your_message” voor elk)?

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}

Antwoord 1, autoriteit 100%

for (var key in validation_messages) {
    // skip loop if the property is from prototype
    if (!validation_messages.hasOwnProperty(key)) continue;
    var obj = validation_messages[key];
    for (var prop in obj) {
        // skip loop if the property is from prototype
        if (!obj.hasOwnProperty(prop)) continue;
        // your code
        alert(prop + " = " + obj[prop]);
    }
}

Antwoord 2, autoriteit 38%

Onder ECMAScript 5 kunt u Object.keys()en Array.prototype.forEach()combineren:

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

Antwoord 3, autoriteit 18%

Het probleem hiermee

for (var key in validation_messages) {
   var obj = validation_messages[key];
   for (var prop in obj) {
      alert(prop + " = " + obj[prop]);
   }
}

is dat je ook door het prototype van het primitieve object loopt.

Met deze vermijd je het:

for (var key in validation_messages) {
   if (validation_messages.hasOwnProperty(key)) {
      var obj = validation_messages[key];
      for (var prop in obj) {
         if (obj.hasOwnProperty(prop)) {
            alert(prop + " = " + obj[prop]);
         }
      }
   }
}

Antwoord 4, autoriteit 4%

Gebruik _.eachvan Underscore.js:

_.each(validation_messages, function(value, key){
    _.each(value, function(value, key){
        console.log(value);
    });
});

Antwoord 5, autoriteit 3%

Als u recursie gebruikt, kunt u objecteigenschappen van elke diepte retourneren-

function lookdeep(object){
    var collection= [], index= 0, next, item;
    for(item in object){
        if(object.hasOwnProperty(item)){
            next= object[item];
            if(typeof next== 'object' && next!= null){
                collection[index++]= item +
                ':{ '+ lookdeep(next).join(', ')+'}';
            }
            else collection[index++]= [item+':'+String(next)];
        }
    }
    return collection;
}
//example
var O={
    a:1, b:2, c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
};
var lookdeepSample= 'O={'+ lookdeep(O).join(',\n')+'}';
/*  returned value: (String)
O={
    a:1, 
    b:2, 
    c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
}
*/

Antwoord 6, autoriteit 2%

Dit antwoord is een aggregaat van de oplossingen die hierin zijn gegeven
post met enkele prestatiefeedbacks. Ik denk dat het er twee zijn
use cases en de OP vermeldde niet of hij toegang nodig heeft tot de sleutels om ze te gebruiken
tijdens het lusproces.

I. De sleutels moeten worden geopend

✔ De ofen Object.keysbenadering

let k;
for (k of Object.keys(obj)) {
    /*        k : key
     *   obj[k] : value
     */
}

✔ De inbenadering

let k;
for (k in obj) {
    /*        k : key
     *   obj[k] : value
     */
}

Gebruik deze met de nodige voorzichtigheid, aangezien het prototype-eigenschappen van obj

kan afdrukken

✔ De ES7-aanpak

for (const [key, value] of Object.entries(obj)) {
}

Ten tijde van de bewerking zou ik echter de ES7-methode niet aanbevelen, omdat JavaScript intern veel variabelen initialiseert om deze procedure te bouwen (zie de feedback voor bewijs). Tenzij u geen enorme applicatie ontwikkelt die optimalisatie verdient, dan is dat oké, maar als optimalisatie uw prioriteit is, moet u erover nadenken.

II. We hebben alleen toegang nodig tot elke waarde

✔ De ofen Object.valuesbenadering

let v;
for (v of Object.values(obj)) {
}

Meer feedback over de tests:

  • Cache Object.keysof Object.valuesprestaties zijn te verwaarlozen

Bijvoorbeeld

const keys = Object.keys(obj);
let i;
for (i of keys) {
  //
}
// same as
for (i of Object.keys(obj)) {
  //
}
  • Voor Object.valueslijkt het gebruik van een native for-lus met variabelen in de cache in Firefox iets sneller dan het gebruik van een for...oflus. Het verschil is echter niet zo belangrijk en Chrome draait for...ofsneller dan de native forloop, dus ik zou aanraden om for...ofbij het omgaan met Object.valuesin ieder geval (4e en 6e test).

  • In Firefox is de for...in-lus erg traag, dus als we de sleutel tijdens de iteratie willen cachen, is het beter om Object.keys. Bovendien voert Chrome beide structuren met gelijke snelheid uit (eerste en laatste test).

Je kunt de tests hier bekijken: https://jsperf.com/es7-and- misc-loops


Antwoord 7

for(var k in validation_messages) {
    var o = validation_messages[k];
    do_something_with(o.your_name);
    do_something_else_with(o.your_msg);
}

Antwoord 8

Een geoptimaliseerde en verbeterde versie van het antwoord van AgileJon:

var key, obj, prop, owns = Object.prototype.hasOwnProperty;
for (key in validation_messages ) {
    if (owns.call(validation_messages, key)) {
        obj = validation_messages[key];
        for (prop in obj ) {
            // Using obj.hasOwnProperty might cause you headache if there is
            // obj.hasOwnProperty = function(){return false;}
            // but 'owns' will always work
            if (owns.call(obj, prop)) {
                console.log(prop, "=", obj[prop]);
            }
        }
    }
}

Antwoord 9

p is de waarde

for (var key in p) {
  alert(key + ' => ' + p[key]);
}

OF

Object.keys(p).forEach(key => { console.log(key, p[key]) })

Antwoord 10

In ES7 kun je het volgende doen:

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

Antwoord 11

for(var key in validation_messages){
    for(var subkey in validation_messages[key]){
        //code here
        //subkey being value, key being 'yourname' / 'yourmsg'
    }
}

Antwoord 12

Een paar manieren om dat te doen…

1)Een tweelaagse for…in loop…

for (let key in validation_messages) {
   const vmKeys = validation_messages[key];
   for (let vmKey in vmKeys) {
      console.log(vmKey + vmKeys[vmKey]);
   }
}

2)Object.key

gebruiken

Object.keys(validation_messages).forEach(key => {
   const vmKeys = validation_messages[key];
   Object.keys(vmKeys).forEach(key => {
    console.log(vmKeys + vmKeys[key]);
   });
});

3)Recursieve functie

const recursiveObj = obj => {
  for(let key in obj){
    if(!obj.hasOwnProperty(key)) continue;
    if(typeof obj[key] !== 'object'){
      console.log(key + obj[key]);
    } else {
      recursiveObj(obj[key]);
    }
  }
}

En noem het zo:

recursiveObj(validation_messages);

Antwoord 13

Een andere optie:

var testObj = {test: true, test1: false};
for(let x of Object.keys(testObj)){
    console.log(x);
}

Antwoord 14

Hier komt de verbeterde en recursieve versie van AgileJon’s oplossing (demo):

function loopThrough(obj){
  for(var key in obj){
    // skip loop if the property is from prototype
    if(!obj.hasOwnProperty(key)) continue;
    if(typeof obj[key] !== 'object'){
      //your code
      console.log(key+" = "+obj[key]);
    } else {
      loopThrough(obj[key]);
    }
  }
}
loopThrough(validation_messages);

Deze oplossing werkt voor allerlei verschillende dieptes.


Antwoord 15

ECMAScript 2017, net een maand geleden afgerond, introduceert Object.values (). Dus nu kun je dit doen:

let v;
for (v of Object.values(validation_messages))
   console.log(v.your_name);   // jimmy billy

Antwoord 16

Ik denk dat het de moeite waard is om erop te wijzen dat jQuery dit netjes oplost met $.each().

Zie: .each()

Voorbeeld:

$('.foo').each(function() {
    console.log($(this));
});

$(this)is het enige item in het object. Verwissel $('.foo')naar een variabele als je de selector-engine van jQuery niet wilt gebruiken.


Antwoord 17

Ik kon het vorige antwoord niet helemaal laten doen wat ik wilde.

Na wat spelen met de andere antwoorden hier, heb ik dit gemaakt. Het is hacky, maar het werkt!

Voor dit object:

var myObj = {
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"}
};

… deze code:

// Get every value in the object into a separate array item ...
function buildArray(p_MainObj, p_Name) {
    var variableList = [];
    var thisVar = "";
    var thisYes = false;
    for (var key in p_MainObj) {
       thisVar = p_Name + "." + key;
       thisYes = false;
       if (p_MainObj.hasOwnProperty(key)) {
          var obj = p_MainObj[key];
          for (var prop in obj) {
            var myregex = /^[0-9]*$/;
            if (myregex.exec(prop) != prop) {
                thisYes = true;
                variableList.push({item:thisVar + "." + prop,value:obj[prop]});
            }
          }
          if ( ! thisYes )
            variableList.push({item:thisVar,value:obj});
       }
    }
    return variableList;
}
// Get the object items into a simple array ...
var objectItems = buildArray(myObj, "myObj");
// Now use them / test them etc... as you need to!
for (var x=0; x < objectItems.length; ++x) {
    console.log(objectItems[x].item + " = " + objectItems[x].value);
}

… produceert dit in de console:

myObj.pageURL = BLAH
myObj.emailBox.model = emailAddress
myObj.emailBox.selector = #emailAddress
myObj.passwordBox.model = password
myObj.passwordBox.selector = #password

18

var obj = {
    name: "SanD",
    age: "27"
}
Object.keys(obj).forEach((key) => console.log(key,obj[key]));

19

Gebruik van ES8-object.Entries () moet een compactere manier zijn om dit te bereiken.

Object.entries(validation_messages).map(([key,object]) => {
    alert(`Looping through key : ${key}`);
    Object.entries(object).map(([token, value]) => {
        alert(`${token} : ${value}`);
    });
});

20

De oplossing die voor mij werkt, is het volgende:

_private.convertParams = function(params){
    var params = [];
    Object.keys(values).forEach(function(key) {
        params.push({"id":key, "option":"Igual", "value":params[key].id})
    });
    return params;
}

21

Exotische One – Deep Traverse

JSON.stringify(validation_messages,(field,value)=>{
  if(!field) return value;
  // ... your code
  return value;
})

In deze oplossing gebruiken we replacerwaarmee u diep door het hele object en geneste objecten kunt gaan – op elk niveau krijgt u alle velden en waarden. Als je het volledige padnaar elk veld nodig hebt, kijk dan hier.


Antwoord 22

In 2020 wil je onveranderlijke en universele functies

Dit doorloopt uw multidimensionale object dat is samengesteld uit subobjecten, arrays en strings en past een aangepaste functie toe:

export const iterate = (object, func) => {
  const entries = Object.entries(object).map(([key, value]) =>
    Array.isArray(value)
      ? [key, value.map(e => iterate(e, func))]
      : typeof value === 'object'
      ? [key, iterate(value, func)]
      : [key, func(value)]
  );
  return Object.fromEntries(entries);
};

Gebruik:

const r = iterate(data, e=>'converted_'+e);
console.log(r);

Antwoord 23

forEach2

(hier):

var lunch = {
    sandwich: 'ham',
    age: 48,
};
lunch.forEach2(function (item, key) {
    console.log(key);
    console.log(item);
});

Code:

if (!Object.prototype.forEach2) {
    Object.defineProperty(Object.prototype, 'forEach2', {
        value: function (callback, thisArg) {
            if (this == null) {
                throw new TypeError('Not an object');
            }
            thisArg = thisArg || window;
            for (var key in this) {
                if (this.hasOwnProperty(key)) {
                    callback.call(thisArg, this[key], key, this);
                }
            }
        }
    });
}

24

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}
for (var i in validation_messages) {
    console.log("i = \"" + i + "\"");
    console.log("validation_messages[\"" + i + "\"] = ");
    console.log(validation_messages[i]);
    console.log("\n");
    for (var j in validation_messages[i]) {
        console.log("j = \"" + j + "\"");
        console.log("validation_messages[\"" + i + "\"][\"" + j + "\"] = \"" + validation_messages[i][j] + "\"");
        console.log("\n");
    }
    console.log('\n');
}

Uitgangen:

i = "key_1"
validation_messages["key_1"] = 
{
  your_name:"jimmy",
  your_msg:"hello world"
}
j = "your_name"
validation_messages["key_1"]["your_name"] = "jimmy"
j = "your_msg"
validation_messages["key_1"]["your_msg"] = "hello world"
i = "key_2"
validation_messages["key_2"] = 
{
  your_name:"billy",
  your_msg:"foo equals bar"
}
j = "your_name"
validation_messages["key_2"]["your_name"] = "billy"
j = "your_msg"
validation_messages["key_2"]["your_msg"] = "foo equals bar"

Antwoord 25

In mijn geval (op basis van het voorgaande) is het mogelijk voor een willekeurig aantal niveaus.

var myObj = {
    rrr: undefined,
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"},
    proba: {odin:{dva:"rr",trr:"tyuuu"}, od:{ff:5,ppa:{ooo:{lll:'lll'}},tyt:'12345'}}
};
function lookdeep(obj,p_Name,gg){
    var A=[], tem, wrem=[], dd=gg?wrem:A;
    for(var p in obj){
        var y1=gg?'':p_Name, y1=y1 + '.' + p;
        if(obj.hasOwnProperty(p)){
           var tem=obj[p];
           if(tem && typeof tem=='object'){
               a1=arguments.callee(tem,p_Name,true);
               if(a1 && typeof a1=='object'){for(i in a1){dd.push(y1 + a1[i])};}
            }
            else{
               dd.push(y1 + ':' + String(tem));
            }
        }
    };
    return dd
};
var s=lookdeep(myObj,'myObj',false);
for (var x=0; x < s.length; ++x) {
console.log(s[x]+'\n');}

Resultaat:

["myObj.rrr:undefined",
"myObj.pageURL:BLAH",
"myObj.emailBox.model:emailAddress",
"myObj.emailBox.selector:#emailAddress",
"myObj.passwordBox.model:password",
"myObj.passwordBox.selector:#password",
"myObj.proba.odin.dva:rr",
"myObj.proba.odin.trr:tyuuu",
"myObj.proba.od.ff:5",
"myObj.proba.od.ppa.ooo.lll:lll",
"myObj.proba.od.tyt:12345"]

Other episodes