जावास्क्रिप्ट ऑब्जेक्ट के गुणों को कैसे सूचीबद्ध करें?


841

इस प्रकार मैं एक वस्तु बनाता हूं:

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

संपत्ति के नामों की सूची प्राप्त करने का सबसे अच्छा तरीका क्या है? यानी मैं कुछ चर 'कुंजियों' को समाप्त करना चाहूंगा जैसे:

keys == ["ircEvent", "method", "regex"]

3
विषय से थोड़ा हटकर, लेकिन यदि आप अंडरस्कोर का उपयोग करते हैं। _.keys(myJSONObject)
जेएस

जवाबों:


1075

आधुनिक ब्राउज़रों (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) में आप ऑब्जेक्ट में निर्मित विधि का उपयोग कर सकते हैं :

var keys = Object.keys(myObject);

ऊपर एक पूर्ण पॉलीफ़िल है लेकिन एक सरलीकृत संस्करण है:

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

वैकल्पिक रूप से बदलने के var getKeysसाथ Object.prototype.keysआप कॉल करने के लिए अनुमति देने के लिए .keys()किसी भी वस्तु पर। प्रोटोटाइप को विस्तारित करने के कुछ दुष्प्रभाव हैं और मैं इसे करने की सलाह नहीं दूंगा।


17
मैं इस आशय के लिए फिर से अद्यतन करूंगा 'आपको प्रोटोटाइप के उद्देश्य से ऐसा करने के लिए लुभाया जा सकता है ... लेकिन नहीं!'
एंथनीवजोन

4
क्या कोई इस पर प्रकाश डालना चाहेगा, ऑब्जेक्ट के प्रोटोटाइप में फ़ंक्शंस जोड़ने की सिफारिश क्यों नहीं की गई है?
विश्वनाथ

2
यह अपने आप में एक पूरी तरह से अलग सवाल है,
स्टैकओवरफ्लो

3
for (var key in myObject) {...}तकनीक ब्राउज़रों और वी 8 के बाहर जावास्क्रिप्ट runtimes लिए उपयोगी है। उदाहरण के लिए, रीवाक में जावास्क्रिप्ट मैप-कम प्रश्नों को पास करते समय Objectऑब्जेक्ट मौजूद नहीं होता है, इसलिए Object.keysविधि उपलब्ध नहीं है।
एखिलाबी

19
@slashnick आपका "सरलीकृत संस्करण" ऑब्जेक्ट की प्रोटोटाइप श्रृंखला में सभी गुणों को लौटाता है (क्योंकि यह "के लिए ..." का उपयोग कर रहा है), जबकि (ECMAScript 5.1) Object.keysविधि केवल ऑब्जेक्ट के अपने गुणों को लौटाती है। मैं इसे एक महत्वपूर्ण अंतर के रूप में देखता हूं।
मार्टिन केयरल

255

जैसा कि स्लैशनिक ने बताया है, आप अपने गुणन नामों के लिए किसी ऑब्जेक्ट पर पुनरावृति करने के लिए "इन" निर्माण का उपयोग कर सकते हैं। हालाँकि आप ऑब्जेक्ट की प्रोटोटाइप श्रृंखला में सभी विशेषता नामों पर पुनरावृत्ति करेंगे। यदि आप केवल ऑब्जेक्ट की अपनी विशेषताओं पर चलना चाहते हैं, तो आप ऑब्जेक्ट # hasOwnProperty () विधि का उपयोग कर सकते हैं । इस प्रकार निम्नलिखित है।

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

25
काश मैंने ऊपर स्लैशनिक के उत्तर से पहले इसे पढ़ा होता। मुझे बस 15 मिनट बिताने पड़े, escक्योंकि चाबी में लगभग एक मिलियन गुण थे, उनमें से अधिकांश का उपयोग नहीं किया गया था, और मुझे इसके बारे में अलर्ट था।
मार्क हेंडरसन

यहाँ खुद ज़कस द्वारा इस विषय पर एक उत्कृष्ट लेख है: nczonline.net/blog/2010/07/27/…
पाब्लो

4
LOL @MarkHenderson - लेकिन अगली बार, बस ब्राउज़र की प्रक्रिया को मारें और इसे 15 मिनट बर्बाद करने के बजाय इसे फिर से शुरू करें :)
JD Smith

एक संबंधित कार्य obj.getOwnPropertyNames () - developer.mozilla.org/en-US/docs/JavaScript/Reference/…
स्टीव गुडमैन

@MarkHenderson आप कंसोल.लॉग का उपयोग क्यों नहीं करेंगे?
लासगनाएंड्रॉइड

102

जैसा कि सैम डटन ने उत्तर दिया, इस उद्देश्य के लिए एक नया तरीका ECMAScript 5 वें संस्करण में पेश किया गया है। Object.keys()वही करेंगे जो आप चाहते हैं और फ़ायरफ़ॉक्स 4 , क्रोम 6, सफारी 5 और आईई 9 में समर्थित है ।

आप बहुत आसानी से ब्राउज़रों में विधि को लागू कर सकते हैं जो इसका समर्थन नहीं करते हैं। हालाँकि, कुछ कार्यान्वयन वहाँ पूरी तरह से इंटरनेट एक्सप्लोरर के साथ संगत नहीं हैं। यहाँ एक और अधिक संगत समाधान है:

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

ध्यान दें कि वर्तमान में स्वीकार किए गए उत्तर में hasOwnProperty () के लिए एक चेक शामिल नहीं है और वे प्रॉपर्टीज़ हैं जो प्रोटोटाइप श्रृंखला के माध्यम से विरासत में मिली हैं। यह इंटरनेट एक्सप्लोरर में प्रसिद्ध डोंटेन्नम बग के लिए भी जिम्मेदार नहीं है, जहां प्रोटोटाइप चेन पर गैर-असंख्य गुण स्थानीय रूप से घोषित गुणों के साथ अपने डॉन्टीनम विशेषता को प्राप्त करने के लिए समान नाम का कारण बनते हैं।

Object.keys () को लागू करने से आपको अधिक मजबूत समाधान मिलेगा।

EDIT: कंगैक्स के साथ हाल ही में चर्चा के बाद , प्रोटोटाइप के लिए एक प्रसिद्ध योगदानकर्ता, मैंने यहांObject.forIn() पाए गए उनके फ़ंक्शन के लिए कोड के आधार पर डोंटएनम बग के लिए समाधान लागू किया ।


महान उत्तर, मुझे लगता है कि स्वीकृत उत्तर सबसे सटीक सटीक समाधान बना हुआ है, यह मानते हुए कि यह हमेशा एक JSON तानाशाही है। यह निश्चित रूप से कहीं और उपयोग करने वाला है।
डेविड स्नेबेल-कॉंट

1
@ डेविड कॉंट: धन्यवाद :-) दुर्भाग्य से, स्वीकृत उत्तर अभी भी डॉन्टनम बग की बेईमानी से गिर जाएगा और आपको कभी नहीं पता होगा कि JSON ऑब्जेक्ट के पास "मान" या "कंस्ट्रक्टर" जैसी स्ट्रिंग में से एक इसकी कुंजी के रूप में हो सकती है। यह भी एक्सटेंशन पर पुनरावृति करेगा Object.prototype। यह अक्सर ऐसा होता है, हालांकि, यह छोटा कोड बड़े, अधिक मजबूत कोड की तुलना में काफी अधिक आकर्षक लगता है, लेकिन इस उत्तर का बिंदु ECMAScript 5th का उपयोग करना है Object.keys(), जिसे उन ब्राउज़रों में लागू किया जा सकता है जो इस कोड का उपयोग करके इसका समर्थन नहीं करते हैं। देशी संस्करण इससे भी अधिक उत्कृष्ट होगा।
एंडी ई

2
बहुत अच्छा, एंडी :) मैं याद दिलाने के लिए की तरह होगा - कोई भी इस सूत्र में उल्लेख करने के लिए लगता है - कि ES5 Object.keysकेवल करने के लिए इसी तार की एक सरणी देता है गणनीय एक वस्तु का गुण। मूल (उपयोगकर्ता-परिभाषित) ऑब्जेक्ट्स के साथ काम करते समय यह महत्वपूर्ण नहीं हो सकता है, लेकिन होस्ट ऑब्जेक्ट्स के साथ बहुत अधिक दिखाई देनी चाहिए (हालांकि अनिर्दिष्ट होस्ट ऑब्जेक्ट व्यवहार एक अलग - दर्दनाक - कहानी है)। सभी पर (नॉन-एन्युमरेबल सहित) संपत्तियों की गणना करने के लिए, ES5 प्रदान करता है Object.getOwnPropertyNames(इसके समर्थन को मेरी संपत्तियों में देखें। तालिका - kangax.github.com/es5-compat-table )
kangax

2
मैंने इस समाधान को es5-shim github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390
Kris Kowal

2
क्या कोई समझा सकता है कि इसे क्यों लागू किया गया है Object.keys(stuff)और क्या नहीं stuff.keys()?
ब्लेज़मॉन्गर

32

ध्यान दें कि Object.key और अन्य ECMAScript 5 विधियाँ फ़ायरफ़ॉक्स 4, क्रोम 6, सफारी 5, IE 9 और इसके बाद के संस्करण द्वारा समर्थित हैं।

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

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ECMAScript 5 संगतता तालिका: http://kangax.github.com/es5-compat-table/

नए तरीकों का विवरण: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/


क्रोम देव टूल्स, फायरबग, आदि के लिए कंसोल में कुंजियों () की भी जांच करें
सैम डटन


28

Object.getOwnPropertyNames(obj)

यह फ़ंक्शन द्वारा दिखाए गए लोगों के अलावा गैर-एन्यूमरेबल गुणों को भी दर्शाता है Object.keys(obj)

जेएस में, प्रत्येक संपत्ति में एक बूलियन सहित कुछ गुण होते हैं enumerable

सामान्य तौर पर, गैर-संवेदी गुण अधिक "आंतरिक" होते हैं और कम अक्सर उपयोग किए जाते हैं, लेकिन यह देखने के लिए कभी-कभी देखने के लिए व्यावहारिक है कि वास्तव में क्या चल रहा है।

उदाहरण:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

यह भी ध्यान दें कि कैसे:

  • Object.getOwnPropertyNamesऔर खोजने के लिए प्रोटोटाइप श्रृंखला ऊपर Object.keys मत जाओbase
  • for in कर देता है

यहाँ प्रोटोटाइप श्रृंखला के बारे में अधिक जानकारी: https://stackoverflow.com/a/23877420/895245


16

मैं डंप फंक्शन का बहुत बड़ा प्रशंसक हूं।

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion वैकल्पिक शब्द


1
+1 क्योंकि मैं यहां कुछ समान बनाने के इरादे से मिला हूं (हालांकि यह उतना अच्छा नहीं है)।
कैमिलो मार्टिन

1
netgrow.com.au/assets/files/dump/dump.zip नहीं मिला मैं डंप जावास्क्रिप्ट कैसे डाउनलोड कर सकता हूं?
किकेनेट

@Kiquenet हर बार जब मैं कुछ इस तरह का निर्माण करना चाहता था, तो मैं नियमित ऑब्जेक्ट इंस्पेक्टर के लिए व्यवस्थित करता हूं, यदि आप चाहते हैं कि HTML में प्रदान की गई चीजें npm मॉड्यूल जैसी चीजें हों । सच कहूं तो मुझे जो कुछ मिला वह है कि मैं उस छवि पर क्या चाहता हूं, उससे बेहतर कुछ चाहता था, लेकिन कभी भी इसे वैचारिक रूप देने में कामयाब नहीं हुआ। यह निरीक्षक में वस्तुओं को ब्राउज़ करने के लिए शर्मीली है, लेकिन मनमाने ढंग से वस्तुओं से अर्थ निकालने की कोशिश और कटौती करने के लिए (उदाहरण के लिए, स्तंभों के साथ तालिकाओं में वस्तुओं के सरणियों को छांटना) हमेशा अभ्यास में काम नहीं करता है।
कैमिलो मार्टिन

सुंदर प्रिंट जावास्क्रिप्ट के बारे में क्या हैhttps://j11y.io/demos/prettyprint/ ?
कीकनेट

13

यह jQuery के साथ इस प्रकार कर सकता है:

var objectKeys = $.map(object, function(value, key) {
  return key;
});

9

यदि आप केवल तत्वों को प्राप्त करने की कोशिश कर रहे हैं, लेकिन कार्य नहीं तो यह कोड आपकी मदद कर सकता है

this.getKeys = function() {

    var keys = new Array();
    for(var key in this) {

        if( typeof this[key] !== 'function') {

            keys.push(key);
        }
    }
    return keys;
}

यह मेरे HashMap के कार्यान्वयन का हिस्सा है और मैं केवल चाबियाँ चाहता हूं, "यह" हैशमैप ऑब्जेक्ट है जिसमें कुंजियां हैं


8

यह IE8 में भी अधिकांश ब्राउज़रों में काम करेगा, और किसी भी प्रकार के किसी भी पुस्तकालय की आवश्यकता नहीं है। var मैं आपकी कुंजी हूं

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

2
आपका उत्तर पहले से ही पोस्ट किए गए लोगों के समान लगता है, जो कुछ भी जोड़ना है?
वीकेन


7

मोज़िला के पास पूर्ण कार्यान्वयन विवरण है कि इसे उस ब्राउज़र में कैसे किया जाए जहां यह समर्थित नहीं है, अगर यह मदद करता है:

if (!Object.keys) {
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
        }
      }
      return result;
    };
  })();
}

हालाँकि, आप इसे शामिल कर सकते हैं, लेकिन संभवतः extensions.jsअपनी स्क्रिप्ट स्टैक के शीर्ष पर किसी प्रकार की फ़ाइल में।


एमडीएन कार्यान्वयन एंडी ई पर आधारित है, जो पहले से ही एक उत्तर के रूप में दिया गया था।
आउट

5

उपयोग Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keys और Object.getOwnPropertyNames को नॉन- एन्यूमरेबल प्रॉपर्टीज़ नहीं मिल सकती हैं। यह गैर-गुणकारी गुणों के लिए भी काम कर रहा है ।

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]

4

IE मूल गुणों के लिए (मैं obj में) का समर्थन नहीं करता है। यहां उन सभी सहारा की सूची दी गई है जो मुझे मिल सकते हैं।

ऐसा लगता है कि stackoverflow कुछ बेवकूफ फ़िल्टरिंग करता है।

सूची इस Google समूह पोस्ट के नीचे उपलब्ध है: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0


4

चूंकि मैं लगभग हर प्रोजेक्ट में अंडरस्कोर.जे का इस्तेमाल करता हूं, इसलिए मैं keysफंक्शन का इस्तेमाल करूंगा :

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

उस का उत्पादन होगा:

['name', 'hello']

यह अक्सर उपयोग की जाने वाली जावास्क्रिप्ट कार्यक्षमता के लिए एक टूलसेट लाइब्रेरी है: underscorejs.org
schmijos

4

स्वीकृत उत्तर पर निर्माण।

यदि ऑब्जेक्ट में ऐसे गुण हैं, जिन्हें आप कहना चाहते हैं .properties () कोशिश करें!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

0

मेरे मामलों और क्रॉस-ब्राउज़र पर समाधान कार्य:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if(isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
            keys.push(i)
        }
    }
    if(keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if(hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.push(prop);
            }
        }

    }

    return keys;
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.