अगर (ऑब्जेक्ट में कुंजी) या यदि (object.hasOwnProperty (कुंजी)


173

क्या निम्नलिखित दो कथन एक ही आउटपुट उत्पन्न करते हैं? क्या किसी भी तरह से दूसरे को पसंद करने का कोई कारण है?

 if (key in object)

 if (object.hasOwnProperty(key))

जवाबों:


181

सावधान रहें - वे समान परिणाम नहीं देंगे।

intrueयदि प्रोटोटाइप श्रृंखलाkey में कहीं पाया जाता है, तो भी वापस आ जाएगा , जबकि (जैसा कि नाम पहले से ही हमें बताता है), केवल तभी वापस लौटेगा जब वह उस वस्तु पर सीधे उपलब्ध होगा (संपत्ति का "मालिक" होगा)।Object.hasOwnPropertytruekey


3
आप के लिए वास्तव में क्या मतलब है in will also return true if key gets found somewhere in the prototype chain। क्या आप एक उदाहरण लिख सकते हैं? धन्यवाद।
लोरेन बर्नार्ड

44
@ लोर: ({foo:"bar"}).hasOwnProperty("toString")बनाम"toString" in ({foo:"bar"})
आई हेट

68

मैं एक और उदाहरण के साथ समझाने की कोशिश करूँगा। कहें कि हमारे पास दो गुणों वाली निम्न वस्तु है:

function TestObj(){
    this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';

चलिए TestObj का उदाहरण बनाते हैं:

var o = new TestObj();

आइए वस्तु उदाहरण की जाँच करें:

console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true

console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true

निष्कर्ष:

  • ऑपरेटर हमेशा सही रिटर्न देता है, अगर संपत्ति वस्तु द्वारा, सीधे या प्रोटोटाइप से सुलभ हो

  • hasOwnProperty () केवल तभी वापस लौटाती है यदि संपत्ति उदाहरण पर मौजूद है, लेकिन इसके प्रोटोटाइप पर नहीं

अगर हम जाँचना चाहते हैं कि कुछ संपत्ति प्रोटोटाइप पर मौजूद है, तो तार्किक रूप से, हम कहेंगे:

console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype

आखिरकार:

इसलिए, इन दो शर्तों के बारे में ...

if (key in object)
if (object.hasOwnProperty(key))

... एक ही परिणाम का उत्पादन, जवाब स्पष्ट है, यह निर्भर करता है।


28

inविरासत में मिली संपत्तियों की भी जांच करेगा, जो कि मामला नहीं है hasOwnProperty


25

सारांश hasOwnProperty()में, प्रोटोटाइप में नहीं दिखता है जबकि प्रोटोटाइप inमें दिखता है।

ओ'रिली उच्च प्रदर्शन जावास्क्रिप्ट से लिया गया :

आप निर्धारित कर सकते हैं कि क्या किसी ऑब्जेक्ट में किसी उदाहरण के साथ hasOwnProperty () विधि का उपयोग करके एक सदस्य है और सदस्य के नाम से गुजर रहा है। यह निर्धारित करने के लिए कि किसी ऑब्जेक्ट में किसी दिए गए नाम के साथ एक संपत्ति है, आप ऑपरेटर में उपयोग कर सकते हैं। उदाहरण के लिए:

var book = {
    title: "High Performance JavaScript",
    publisher: "Yahoo! Press" 
};

alert(book.hasOwnProperty("title"));  //true
alert(book.hasOwnProperty("toString"));  //false
alert("title" in book); //true 
alert("toString" in book); //true

इस कोड में, hasOwnProperty () सही है जब "शीर्षक" पारित किया जाता है क्योंकि शीर्षक एक वस्तु उदाहरण है; विधि तब झूठी हो जाती है जब "toString" पारित हो जाता है क्योंकि यह उदाहरण पर मौजूद नहीं है। जब प्रत्येक गुण नाम ऑपरेटर के साथ उपयोग किया जाता है, तो परिणाम दोनों बार सही होता है क्योंकि यह उदाहरण और प्रोटोटाइप को खोजता है।


5

आपको कुछ बहुत बढ़िया जवाब मिले। मैं बस एक ऐसी चीज की पेशकश करना चाहता हूं, जो आपको किसी ऑब्जेक्ट की पुनरावृत्ति करते समय "hasOwnProperty" की जांच करने की आवश्यकता को बचाएगा।

ऑब्जेक्ट बनाते समय आमतौर पर लोग इसे इस तरह से बनाएंगे:

const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }

अब, यदि आप "someMap" के माध्यम से पुनरावृति करना चाहते हैं, तो आपको इसे इस तरह करना होगा:

const key
for(key in someMap ){
 if (someMap.hasOwnProperty(key)) { 
   // Do something
 }
}

हम ऐसा विरासत में मिली संपत्तियों पर ध्यान देने से बचने के लिए कर रहे हैं।

यदि आप एक सरल ऑब्जेक्ट बनाने का इरादा रखते हैं जो केवल "मानचित्र" के रूप में उपयोग किया जाएगा (यानी कुंजी - मूल्य जोड़े) आप इस तरह कर सकते हैं:

const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined

इसलिए अब इस तरह से इसे सुरक्षित करना सुरक्षित होगा:

for(key in cleanMap){
 console.log(key + " -> " + newMap [key]);
 // No need to add extra checks, as the object will always be clean
}

मैंने यहां इस भयानक टिप को सीखा


1
एक और अधिक विस्तृत लेखन: ryanmorr.com/true-hash-maps-in-javascript
darcher

2

अन्य रूप (के लिए कहा जाता है) एक वस्तु के संपत्ति के नाम (या कुंजी) enumerates। प्रत्येक पुनरावृत्ति पर, ऑब्जेक्ट से एक और संपत्ति नाम स्ट्रिंग चर को सौंपा गया है। यह निर्धारित करने के लिए आम तौर पर ऑब्जेक्ट का परीक्षण करना आवश्यक है। यह निर्धारित करने के लिए कि क्या प्रॉपर्टी का नाम वास्तव में ऑब्जेक्ट का सदस्य है या इसके बजाय प्रोटोटाइप चेन पर पाया गया था।

 for (myvar in obj) {
     if (obj.hasOwnProperty(myvar)) { ... } }

(क्रॉकफोर्ड के जावास्क्रिप्ट से: द गुड पार्ट्स )


5
inऑपरेटर से अलग है for-inबयान।
हेट लज़ीज़

असल में उन दोनों को कीवर्ड में के विभिन्न उपयोगों के हैं
जहान

4
हाँ, inएक कीवर्ड है। लेकिन ओपी inऑपरेटर के रूप में विशिष्ट उपयोग के बारे में पूछ रहा है । आपका उत्तर for-inकथन के भाग के रूप में अन्य उपयोग से संबंधित है।
हेट लज़ीज़

-3

पहला संस्करण छोटा है (विशेष रूप से छोटा कोड में, जहाँ चर का नाम बदला गया है)

a in b

बनाम

b.hasOwnProperty(a)

वैसे भी, @AndreMeinhold ने कहा, वे हमेशा एक ही परिणाम नहीं देते हैं।


1
टिप्पणी के रूप में ऐसा करना बेहतर होता। :-)
हेलावुल्का मास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.