Object.getOwnPropertyNames बनाम Object.keys


213

जावास्क्रिप्ट में Object.getOwnPropertyNamesऔर क्या अंतर है Object.keys? इसके अलावा कुछ उदाहरणों की सराहना की जाएगी।


3
दोनों पर एमडीएन के लेखों को देखते हुए, अंतर यह है कि क्या लौटी हुई सूची में गैर-गुणांक गुण शामिल हैं: Object.keys()उन्हें वापस नहीं करता है, जबकि Object.getOwnPropertyNames()करता है।
सिरको

जवाबों:


289

थोड़ा अंतर है। वस्तु के सभी गुणों को Object.getOwnPropertyNames(a)लौटाता है । सभी प्राप्य स्वयं के गुणों को लौटाता है । इसका अर्थ है कि यदि आप उनमें से कुछ को बनाए बिना अपनी वस्तु गुणों को परिभाषित करते हैं, तो ये दो विधियां आपको एक ही परिणाम देंगी।aObject.keys(a)enumerable: false

यह परीक्षण करना आसान है:

var a = {};
Object.defineProperties(a, {
    one: {enumerable: true, value: 'one'},
    two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]

यदि आप संपत्ति गुण वर्णनकर्ता प्रदान किए बिना किसी संपत्ति को परिभाषित करते हैं ( Object.definePropertiesउदाहरण के लिए, जिसका आप उपयोग नहीं करते हैं ), उदाहरण के लिए:

a.test = 21;

तब ऐसी संपत्ति स्वचालित रूप से एक पहेली बन जाती है और दोनों विधियाँ एक ही सरणी का उत्पादन करती हैं।


26
विशेष रूप से, lengthसरणी ऑब्जेक्ट्स के गुण गणना योग्य नहीं हैं, इसलिए यह दिखाई नहीं देता है Object.keys
बरमार

6
@ बरमार lengthवस्तुओं का गुण प्रोटोटाइप पर होता है, न कि वस्तु पर, इसलिए न तो इसे सूचीबद्ध करेगा Object.keysऔर न ही Object.getOwnPropertyNames
कूदेस्मिथ

9
@ TheQodesmith के परिणाम में Object.getOwnPropertyNames(anyArray)शामिल हैंlength
कांटा

6
मुझे सही साबित होना है! Object.getOwnPropertyNames(anyArray)वास्तव lengthमें लौटे सरणी में शामिल है!
Qodesmith

हाँ, लेकिन Array.prototype के पास भी है। यह अजीब तरह का है कि एक सामान्य सरणी की तरह Array.prototype को संशोधित कर सकता है (यानी Array.prototype.push ('जो भी हो))। लेकिन नए बने एरियर के उदाहरणों पर इसका कोई असर नहीं दिख रहा है। stackoverflow.com/questions/48020958/…
ट्रोलकोटेज़

21

एक और अंतर सरणी Object.getOwnPropertyNamesविधि के मामले में है जो एक अतिरिक्त संपत्ति लौटाएगा length

var x = ["a", "b", "c", "d"];
Object.keys(x);  //[ '0', '1', '2', '3' ]
Object.getOwnPropertyNames(x);  //[ '0', '1', '2', '3', 'length' ]

1

ऑब्जेक्ट बनाते समय शाब्दिक संकेतन बनाम कंस्ट्रक्टर। यहाँ कुछ ऐसा है जो मुझे मिला है।

const cat1 = {
    eat() {},
    sleep() {},
    talk() {}
};

// here the methods will be part of the Cat Prototype
class Cat {
    eat() {}
    sleep() {}
    talk() {}
}

const cat2 = new Cat()

Object.keys(cat1) // ["eat", "sleep", "talk"]
Object.keys(Object.getPrototypeOf(cat2)) // []

Object.getOwnPropertyNames(cat1) // ["eat", "sleep", "talk"]
Object.getOwnPropertyNames(Object.getPrototypeOf(cat2)) // ["eat", "sleep", "talk"]

cat1 // {eat: function, sleep: function, talk: function}
cat2 // Cat {}

// a partial of a function that is used to do some magic redeclaration of props
function foo(Obj) {
    var propNames = Object.keys(Obj);

    // I was missing this if
    // if (propNames.length === 0) {
    //     propNames = Object.getOwnPropertyNames(Obj);
    // }

    for (var prop in propNames) {
        var propName = propNames[prop];

        APIObject[propName] = "reasign/redefine or sth";
    }
}

तो fooअगर मैं इसे cat2 प्रकार की वस्तुएं देता हूं तो मेरे मामले में यह काम नहीं करता है।

वस्तुओं को बनाने के अन्य तरीके हैं ताकि वहाँ भी अन्य किंक हो सकें।


Object.getOwnPropertyNamescat1और नहीं के लिए संपत्ति के नाम वापस कर देंगे cat2। ऑब्जेक्ट बनाने के दो तरीके Object.getOwnPropertyNamesऔर के बीच अंतर पैदा नहीं करते हैं Object.keys
बोरिक

1
@ बोरिक हाँ आप सही हैं। मैं सिर्फ cat2 के बजाय दोनों तरीकों के साथ Object.getPrototypeOf (cat2) का उपयोग करने के लिए हो सकता है। मुझे यकीन नहीं है क्योंकि मुझे याद नहीं है और कोड नहीं है। मैं जवाब में इसे ठीक कर दूंगा।
h3dkandi

0

जैसा कि पहले ही समझाया जा चुका था, .keysअसंख्य गुणों को वापस नहीं करता है।

उदाहरणों के संबंध में, गड्ढे के मामलों में से एक एक Errorवस्तु है: इसके कुछ गुण हैं।
इसलिए console.log(Object.keys(new Error('some msg')))उपज देते समय [], console.log(Object.getOwnPropertyNames(new Error('some msg')))पैदावार["stack", "message"]

console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));


-5

एक और अंतर यह है कि (कम से कम नोडज के साथ) "getOwnPropertyNames" फ़ंक्शन कुंजियों के आदेश की गारंटी नहीं देता है, इसलिए मैं आमतौर पर "कुंजियों" फ़ंक्शन का उपयोग करता हूं:

    Object.keys(o).forEach(function(k) {
      if (!o.propertyIsEnumerable(k)) return;
      // do something...
    });

1
क्या यह अभी भी Node.js के वर्तमान संस्करणों में मामला है, और यदि हां, तो क्या आप getOwnPropertyNamesक्रम में नहीं होने के किसी भी उदाहरण को जानते हैं ? क्योंकि ES2015 के लिए एक आदेशObect.getOwnPropertyNames निर्दिष्ट करता है , जबकि आदेश के लिएObect.keys अभी भी कार्यान्वयन तक है।
szupie

7
मुझे हमेशा लगता था कि जेएस ऑब्जेक्ट कुंजियों का कोई आदेश नहीं था और आपको इस पर भरोसा नहीं करना चाहिए भले ही एक कार्यान्वयन आदेश रखता हो?
जुआन मेंडेस

1
उम, मुझे लगता है कि यह दूसरा रास्ता है; getOwnPropertyNames का ऑर्डर कल्पना में परिभाषित किया गया है। Object.keys कार्यान्वयन तक है।
tjvr

1
निम्न में से सभी अनिर्दिष्ट आदेश है: for-in loop, Object.keys, और Object.getOwnPropertyNames। उस ने कहा, तीनों एक दूसरे के संबंध में एक सुसंगत क्रम में गणना करेंगे।
थॉमस का संपादन करने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.