सदस्यों के रूप में वस्तुओं के साथ एक सादे जावास्क्रिप्ट ऑब्जेक्ट के माध्यम से लूप कैसे करें?


1599

मैं जावास्क्रिप्ट ऑब्जेक्ट में सभी सदस्यों के माध्यम से कैसे मानों सहित लूप कर सकता हूं।

उदाहरण के लिए, मैं इसके माध्यम से कैसे लूप कर सकता हूं (प्रत्येक के लिए "your_name" और "your_message" तक पहुंचना)?

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

जवाबों:


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

13
जब आप obj [Prop] करते हैं तो Internet Explorer सहमत नहीं होता है ( आह ), "ऑब्जेक्ट इस संपत्ति या पद्धति का समर्थन नहीं करता है"। मुझे अभी तक इसका हल नहीं ढूंढना है।
user999717 12

2
@ माइल्डफज वास्तव में यह समझ में आता है यदि आप समझते हैं कि जेएस ऑब्जेक्ट्स के पास संख्यात्मक कुंजी नहीं है। आप किसी वस्तु के माध्यम से केवल पुनरावृति नहीं कर सकते। जेएस for inएक पारंपरिक के समान है foreach
जेक विल्सन

4
के लिए ... एक अच्छा समाधान है, लेकिन अगर आप () में वादों का उपयोग करते हैं - लूप सावधान रहें, क्योंकि यदि आप लूप में एक वेरिएंट बनाते हैं, तो आप इसे वादे के 'फंक्शन' में इस्तेमाल नहीं कर सकते। आप लूप में var केवल एक समय में मौजूद होते हैं, इसलिए यह हर तत्कालीन फ़ंक्शन में होता है, यहां तक ​​कि अंतिम मान भी। यदि आपको वह समस्या है, तो नीचे दिए गए "Object.keys (obj) .forEach" या मेरे उत्तर का प्रयास करें।
बीबर

775

ECMAScript 5 के अंतर्गत, आप को जोड़ सकते हैं Object.keys()और Array.prototype.forEach():

var obj = {
  first: "John",
  last: "Doe"
};

//
//	Visit non-inherited enumerable keys
//
Object.keys(obj).forEach(function(key) {

  console.log(key, obj[key]);

});


34
+1 कोड की संक्षिप्तता के लिए, लेकिन जाहिरा तौर पर, आश्चर्यजनक रूप से के रूप में कुशल प्रदर्शन नहीं करता है। JSPerf - के लिए बनाम Object.keys
techiev2

6
इस दृष्टिकोण का उपयोग करते हुए इस त्रुटि से सावधान रहें: "TypeError: Object.keys जिसे गैर-ऑब्जेक्ट कहा जाता है"। for ... in ... hasOwnPropertyपैटर्न, कुछ भी पर कहा जा सकता है जहाँ तक मैं (वस्तु, सरणी, अशक्त, अपरिभाषित, सच है, झूठी, संख्या आदिम, वस्तुओं) बता सकते हैं।
theazureshadow

2
ध्यान दें कि IE7 इसका समर्थन नहीं करता है।
पॉल डी। वेट

3
@ Techiev2 वे परीक्षण कभी मान्य नहीं थे। प्रदर्शन की वर्तमान स्थिति के लिए मेरे अपडेट किए गए वीडियो देखें: jsperf.com/objdir/20
OrganicPanda

4
@ techiev2: यह ऐसा नहीं है Object.keys()जो इसे धीमा बनाता है, बल्कि यह forEach()और बार-बार होने वाली पहुंच है .length! यदि आप forइसके बजाय एक क्लासिक- लूप का उपयोग करते हैं, तो यह फ़ायरफ़ॉक्स 33 में for..in+ के रूप में लगभग दोगुना है hasOwnProperty()
CodeManX

384

इससे समस्या हुई

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

यह है कि आप भी आदिम वस्तु के प्रोटोटाइप के माध्यम से लूप करेंगे।

इससे आप इससे बचेंगे:

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

46
संक्षेप में: hasOwnPropertyअपने अंदर की जाँच करें for- inछोरों।
रोरी ओ'केन

59
ध्यान दें कि यह केवल तभी आवश्यक है जब आपकी वस्तु प्रोटोटाइप तरीके हो। उदाहरण के लिए, यदि आप जिस वस्तु के माध्यम से लूपिंग कर रहे हैं वह सिर्फ एक JSON ऑब्जेक्ट है, तो आपको इस चेक की आवश्यकता नहीं होगी।
गीताकार

6
@rednaw सुरक्षित होने के लिए मैं उस चेक का उपयोग करता हूं क्योंकि Object.prototype को संशोधित किया जा सकता है। कोई भी स्क्रिप्ट स्क्रिप्ट ऐसा नहीं करेगी, लेकिन आप यह नहीं नियंत्रित कर सकते हैं कि आपके पेज में कौन-कौन सी स्क्रिप्ट चल सकती हैं। ब्राउज़र एक्सटेंशन आपके पृष्ठ पर चलते हैं (अधिकांश ब्राउज़र पर) और वे विषम समस्याएं पैदा कर सकते हैं (जैसे कि window.setTimeout to null)।
रोबोकट

1
बहुत बहुत धन्यवाद
ब्लू ट्राम

328

में ES6 / 2015 आप इस तरह एक वस्तु के माध्यम से लूप कर सकते हैं: (का उपयोग करते हुए तीर समारोह )

Object.keys(myObj).forEach(key => {
  console.log(key);        // the name of the current key.
  console.log(myObj[key]); // the value of the current key.
});

jsbin

में ES7 / 2016 आप उपयोग कर सकते हैं Object.entriesके बजाय Object.keysइस तरह एक वस्तु के माध्यम से और पाश:

Object.entries(myObj).forEach(([key, val]) => {
  console.log(key); // the name of the current key.
  console.log(val); // the value of the current key.
});

ऊपर भी एक लाइनर के रूप में काम करेगा :

Object.entries(myObj).forEach(([key, val]) => console.log(key, val));

jsbin

यदि आप नेस्टेड ऑब्जेक्ट्स के माध्यम से भी लूप करना चाहते हैं, तो आप पुनरावर्ती फ़ंक्शन (ES6) का उपयोग कर सकते हैं :

const loopNestedObj = obj => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") loopNestedObj(obj[key]); // recurse.
    else console.log(key, obj[key]); // or do something with key and val.
  });
};

jsbin

ऊपर फ़ंक्शन के समान, लेकिन इसके बजाय ES7 के साथ :Object.entries()Object.keys()

const loopNestedObj = obj => {
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === "object") loopNestedObj(val); // recurse.
    else console.log(key, val); // or do something with key and val.
  });
};

यहां हम नेस्टेड ऑब्जेक्ट्स के माध्यम से लूप बदलते हैं और वैल्यू बदलते हैं ( ES10 / 2019 ) के Object.entries()साथ मिलकर एक नए ऑब्जेक्ट को वापस करते हैं :Object.fromEntries()

const loopNestedObj = obj =>
  Object.fromEntries(
    Object.entries(obj).map(([key, val]) => {
      if (val && typeof val === "object") [key, loopNestedObj(val)]; // recurse
      else [key, updateMyVal(val)]; // or do something with key and val.
    })
  );

2
आपके ES7 के लिए Object.entries उदाहरण का उपयोग करते हुए, आपको कोष्ठक में तीर फ़ंक्शन मापदंडों [कुंजी, वैल] को लपेटने की आवश्यकता है जैसे: `Object.entries (myObj) .forEach (([key, val]) => {{* statement *। /}
पुईउ

6
मुझे लगता है कि यह इस तथ्य को जोड़ने के लिए उपयोगी होगा कि Object.entries और Object.keys प्रोटोटाइप पर पुनरावृति नहीं करते हैं, जो इसके और निर्माण में बड़े अंतर के बीच है।
स्टेविजय

बहुत बहुत धन्यवाद
ब्लू ट्राम

95

Underscore.js का_.each उपयोग करना :

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

4
धन्यवाद टिम, अंडरस्कोर का उपयोग करके निश्चित रूप से एक त्वरित और स्वच्छ विकल्प का उपयोग करना अच्छा है।
कोडर

56

यदि आप पुनरावृत्ति का उपयोग करते हैं तो आप किसी भी गहराई के ऑब्जेक्ट गुण वापस कर सकते हैं-

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
}

*/

2
छोरों से सावधान रहें, जैसे कि DOM नोड पर यह कॉल करना।
theazureshadow

45

यह उत्तर उन समाधानों का एक समूह है जो इस पोस्ट में कुछ प्रदर्शन फीडबैक के साथ प्रदान किए गए थे । मुझे लगता है कि 2 उपयोग-मामले हैं और ओपी ने उल्लेख नहीं किया है कि क्या उन्हें लूप प्रक्रिया के दौरान कुंजियों का उपयोग करने की आवश्यकता है।

I. कुंजियों को एक्सेस करने की आवश्यकता है,

ofऔर Object.keysदृष्टिकोण

let k;
for (k of Object.keys(obj)) {

    /*        k : key
     *   obj[k] : value
     */
}

inदृष्टिकोण

let k;
for (k in obj) {

    /*        k : key
     *   obj[k] : value
     */
}

सावधानी के साथ इस का उपयोग करें, क्योंकि यह प्रोटोटाइप के गुणों को प्रिंट कर सकता है obj

ES ES7 दृष्टिकोण

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

}

हालाँकि, संपादन के समय मैं ES7 विधि की सिफारिश नहीं करूंगा, क्योंकि जावास्क्रिप्ट इस प्रक्रिया को बनाने के लिए आंतरिक रूप से बहुत सारे चर को शुरू करता है (प्रमाण के लिए फीडबैक देखें)। जब तक आप एक बहुत बड़ा ऐप विकसित नहीं कर रहे हैं जो अनुकूलन के योग्य है, तो यह ठीक है लेकिन यदि अनुकूलन आपकी प्राथमिकता है तो आपको इसके बारे में सोचना चाहिए।

द्वितीय। हमें बस प्रत्येक मूल्यों का उपयोग करने की आवश्यकता है,

ofऔर Object.valuesदृष्टिकोण

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

}

परीक्षणों के बारे में अधिक प्रतिक्रिया:

  • कैशिंग Object.keysया Object.valuesप्रदर्शन नगण्य है

उदाहरण के लिए,

const keys = Object.keys(obj);
let i;
for (i of keys) {
  //
}
// same as
for (i of Object.keys(obj)) {
  //
}
  • के लिए Object.valuesमामला है, एक देशी का उपयोग कर forफ़ायरफ़ॉक्स में कैश चर के साथ पाश एक का उपयोग कर की तुलना में थोड़ा तेजी से हो रहा है for...ofपाश। हालांकि अंतर यह नहीं है कि महत्वपूर्ण और क्रोम for...ofदेशी forलूप की तुलना में तेजी से चल रहा है , इसलिए मैं किसी भी मामले (4 वें और 6 वें परीक्षणों) से for...ofनिपटने के Object.valuesदौरान उपयोग करने की सलाह दूंगा।

  • फ़ायरफ़ॉक्स में, for...inलूप वास्तव में धीमा है, इसलिए जब हम पुनरावृत्ति के दौरान कुंजी को कैश करना चाहते हैं तो इसका उपयोग करना बेहतर होता है Object.keys। साथ ही क्रोम समान गति (प्रथम और अंतिम परीक्षण) पर दोनों संरचना चला रहा है।

आप यहां परीक्षण देख सकते हैं: https://jsperf.com/es7-and-misc-loops


2
ES7 उदाहरण प्रतिक्रिया मूल निवासी के साथ एक आकर्षण की तरह काम करता है!
टाइ बेली 20

अच्छी तरह से समझाया गया। धन्यवाद
आलोक रंजन

30

मुझे पता है कि यह देर से खत्म हो रहा है, लेकिन AgileJon के उत्तर के इस अनुकूलित और बेहतर संस्करण को लिखने में मुझे 2 मिनट का समय लगा:

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

        }

    }

}

1
तुम क्यों भंडारण कर रहे हैं hasOwnPropertyमें ownsऔर फिर बुला owns.call(obj, prop)के बजाय सिर्फ बुला obj.hasOwnProperty(prop)के रूप में इस सवाल का जवाब है?
रोरी ओ'केन

14
क्योंकि objहो सकता है कि hasOwnPropertyफ़ंक्शन स्वयं पर परिभाषित किया गया हो, इसलिए यह उस से उपयोग नहीं करेगा Object.prototype। आप forइस तरह लूप से पहले कोशिश कर सकते हैं obj.hasOwnProperty = function(){return false;}और यह किसी भी संपत्ति पर पुनरावृत्ति नहीं करेगा।
एज्डर

4
उत्तर के लिए @Azder +1 और अगर मैं Object.prototyp.hasOwnProperty के बारे में अच्छी बात कर सकता हूं। मैंने देखा कि पहले अंडरस्कोर लाइब्रेरी के स्रोत कोड के अंदर लेकिन पता नहीं क्यों।
शमूएल


14

p मान है

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

या

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

9

ES7 में आप यह कर सकते हैं:

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

मैंने कुछ परीक्षण किए, बड़ी मात्रा में डेटा के साथ काम करते समय यह विधि बहुत धीमी है।
vdegenne


7

ऐसा करने के कुछ तरीके ...

1) लूप में ... के लिए 2 परतें ...

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

२) उपयोग करनाObject.key

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

3) पुनरावर्ती कार्य

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

और इसे कॉल करें:

recursiveObj(validation_messages);

5

यहाँ AgileJon के समाधान ( डेमो) का बेहतर और पुनरावर्ती संस्करण आता है ) :

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

यह समाधान सभी प्रकार की अलग-अलग गहराई के लिए काम करता है।


5

एक अन्य विकल्प:

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

मैंने Chrome 55.0 में आपके समाधान की कोशिश की और आपको एक प्रकार की त्रुटि मिली। आपका उत्तर अच्छा और सक्सेफुल लगता है, अगर आप इसे काम करते हुए पा सकते हैं तो यह शायद बेहतर विकल्पों में से एक होगा। मैंने इसका पता लगाने की कोशिश की लेकिन आपके समाधान को नहीं समझा।
तोलमेरा

2
@ टॉलमेरा फिक्स्ड।
दोस्त

4

ECMAScript-2017, अभी एक महीने पहले अंतिम रूप से, Object.values ​​() पेश करता है। तो अब आप यह कर सकते हैं:

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

3

मुझे लगता है कि यह इंगित करने के लायक है कि jQuery इस तरह अच्छी तरह से बाहर है $.each()

देखें: https://api.jquery.com/each/

उदाहरण के लिए:

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

$(this)वस्तु के अंदर एकल वस्तु होना। $('.foo')यदि आप jQuery के चयनकर्ता इंजन का उपयोग नहीं करना चाहते हैं तो एक चर पर स्वैप करें।


3

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

जावास्क्रिप्ट ऑब्जेक्ट के माध्यम से लूप करने के लिए हम फॉरएच का उपयोग कर सकते हैं और कोड का अनुकूलन करने के लिए हम एरो फ़ंक्शन का उपयोग कर सकते हैं


2

मुझे उपरोक्त पोस्ट करने के लिए काफी कुछ नहीं मिला जो मैं था।

यहाँ अन्य उत्तरों के साथ खेलने के बाद, मैंने इसे बनाया। यह हैक है, लेकिन यह काम करता है!

इस वस्तु के लिए:

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

... यह कोड:

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

... कंसोल में यह उत्पादन:

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

0

मेरे लिए काम करने वाला समाधान निम्नलिखित है

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

0

विदेशी एक - गहरा पार

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

  // ... your code

  return value;
})

इस समाधान में हम प्रतिकृति का उपयोग करते हैं जो पूरे ऑब्जेक्ट और नेस्टेड ऑब्जेक्ट को गहराई से पार करने की अनुमति देता है - प्रत्येक स्तर पर आपको सभी फ़ील्ड और मान मिलेंगे। यदि आपको प्रत्येक क्षेत्र को देखने के लिए पूर्ण पथ प्राप्त करने की आवश्यकता है


-6

मेरे मामले में (पूर्ववर्ती के आधार पर) किसी भी स्तर के स्तर पर संभव है।

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

परिणाम:

["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"]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.