जावास्क्रिप्ट में मानचित्र बनाम वस्तु


290

मैंने अभी-अभी chromestatus.com की खोज की और, अपने दिन के कई घंटे खोने के बाद, यह सुविधा प्रविष्टि मिली :

मानचित्र: मानचित्र वस्तुएँ सरल कुंजी / मान मानचित्र हैं।

इसने मुझे भ्रमित कर दिया। रेगुलर जावास्क्रिप्ट ऑब्जेक्ट्स डिक्शनरी हैं, तो डिक्शनरी से कैसे Mapअलग है? वैचारिक रूप से, वे समान हैं ( मानचित्र और शब्दकोश के बीच अंतर क्या है? )

प्रलेखन क्रोमैस्टेटस संदर्भ या तो मदद नहीं करता है:

मानचित्र वस्तुएं कुंजी / मूल्य युग्मों का संग्रह होती हैं, जहां कुंजी और मान दोनों ही ईसीएमएस्क्रिप्ट भाषा मानों की मनमानी हो सकती है। एक अलग कुंजी मूल्य केवल मानचित्र के संग्रह के भीतर एक कुंजी / मूल्य जोड़ी में हो सकता है। मानचित्र बनाए जाने पर चुने गए तुलनात्मक एल्गोरिथ्म का उपयोग करके विभेदित प्रमुख मानों का भेदभाव किया जाता है।

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

... अभी भी मुझे एक वस्तु की तरह लगता है, तो स्पष्ट रूप से मैंने कुछ याद किया है।

जावास्क्रिप्ट एक (अच्छी तरह से समर्थित) Mapवस्तु क्यों प्राप्त कर रहा है ? यह क्या करता है?


जवाबों:


286

मोज़िला के अनुसार:

एक मानचित्र ऑब्जेक्ट सम्मिलन क्रम में अपने तत्वों को पुनरावृत्त कर सकता है - प्रत्येक पुनरावृत्ति के लिए for..of लूप [कुंजी, मान] की एक सरणी लौटाएगा।

तथा

ऑब्जेक्ट मैप्स के समान हैं जिसमें दोनों आपको मानों की कुंजी सेट करने देते हैं, उन मानों को पुनः प्राप्त करते हैं, कुंजियों को हटाते हैं, और पता लगाते हैं कि क्या किसी कुंजी पर संग्रहीत है। इस वजह से, वस्तुओं का उपयोग ऐतिहासिक रूप से मानचित्र के रूप में किया गया है; हालाँकि, ऑब्जेक्ट और मैप्स के बीच महत्वपूर्ण अंतर हैं जो मैप का बेहतर उपयोग करते हैं।

ऑब्जेक्ट में एक प्रोटोटाइप होता है, इसलिए मैप में डिफ़ॉल्ट कुंजियाँ होती हैं। हालांकि, यह मैप = Object.create (नल) का उपयोग करके बाईपास किया जा सकता है। किसी ऑब्जेक्ट की कुंजी स्ट्रिंग्स हैं, जहां वे किसी मैप के लिए कोई भी मूल्य हो सकते हैं। आपको किसी ऑब्जेक्ट के लिए मैन्युअल रूप से ट्रैक रखने के दौरान मैप का आकार आसानी से मिल सकता है।

जब समय चल रहा हो तब तक कुंजियाँ अज्ञात हों, और जब सभी कुंजियाँ एक ही प्रकार की हों और सभी मान एक ही प्रकार के हों, तब मानचित्रों का उपयोग करें।

ऑब्जेक्ट का उपयोग तब करें जब व्यक्तिगत तत्वों पर काम करने वाले तर्क हों।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

Iterability-in-order एक ऐसी सुविधा है जो लंबे समय से डेवलपर्स द्वारा वांछित है, क्योंकि यह सभी ब्राउज़रों में समान प्रदर्शन सुनिश्चित करता है। तो मेरे लिए यह एक बड़ी बात है।

myMap.has(key)विधि विशेष रूप से उपयोगी है, और यह भी हो सकता है myMap.sizeसंपत्ति।


13
एक नकारात्मक पहलू यह है कि प्रविष्टि क्रम को बनाए रखने के लिए मानचित्र में अधिक मेमोरी (परिमाण के समान क्रम के भीतर, हालांकि) की आवश्यकता होती है।
जॉन कुर्लाक

4
मैप्स में अन्य विशेषताओं के अलावा क्रमबद्धता भी है जिसका उल्लेख यहां किया गया है (किसी भी वस्तु को कुंजी के रूप में उपयोग करते हुए, कुंजी और प्रॉप्स के पृथक्करण आदि), लेकिन एफडब्ल्यूआईडब्ल्यू कुछ मामलों में सादे वस्तु गुणों के पुनरावृत्ति क्रम को ES2015 द्वारा परिभाषित किया गया है। देखें stackoverflow.com/a/32149345
JMM

2
मुझे यह अर्थ नहीं मिला, जब आप कहते हैं, एक ऑब्जेक्ट में एक प्रोटोटाइप है, इसलिए नक्शे में डिफ़ॉल्ट कुंजी हैं। हालाँकि, इसका उपयोग करके बाईपास किया जा सकता हैmap = Object.create(null) । डिफ़ॉल्ट कुंजियाँ क्या हैं? कैसे कुंजी से संबंधित हैं Object.prototype?
ओवरएक्सचेंज

4
Chrome में मेरे परीक्षणों से पता चला कि ऑर्डर बनाए रखने के लिए नक्शे किसी भी महत्वपूर्ण राशि का अधिक मेमोरी का उपयोग नहीं करते हैं। मुझे लगता है कि एक लाख कुंजी के लिए 0.1KB अधिक था और मुझे नहीं लगता कि ऑर्डर बनाए रखने के लिए था। हालाँकि, यह ~ 0.1KB एक निरंतर ओवरहेड लगता है। यदि आप इसके बजाय एक कुंजी के साथ एक लाख मानचित्र बनाते हैं और तुलना करते हैं तो यह ऑब्जेक्ट से बहुत बड़ा है।
jgmjgm

2
@ लक्सॉन आप वहां एक ऑब्जेक्ट बना रहे हैं। ES6 युक्ति के लिए newऑपरेटर के साथ Mapप्रतीक का उपयोग करने की आवश्यकता होती है अर्थात new Mapइसके लिए एक मानचित्र ऑब्जेक्ट बनाने के लिए। var a = {}के लिए आशुलिपि है (जिसका अर्थ है समकक्ष)var a = Object.create(Object.prototype)
dudewad

104

मुख्य अंतर यह है कि ऑब्जेक्ट केवल स्ट्रिंग कुंजियों का समर्थन करते हैं, जहां मैप्स अधिक या कम कुंजी प्रकार का समर्थन करते हैं।

अगर मैं करता हूं obj[123] = trueऔर फिर Object.keys(obj)मैं इसके ["123"]बजाय मिलूंगा [123]। एक मानचित्र कुंजी और वापसी के प्रकार को संरक्षित करेगा [123]जो महान है। मैप्स आपको कुंजी के रूप में ऑब्जेक्ट का उपयोग करने की अनुमति भी देते हैं। परंपरागत रूप से ऐसा करने के लिए आपको वस्तुओं को किसी तरह के विशिष्ट पहचानकर्ता को हैश करने के लिए देना होगा (मुझे नहीं लगता कि मैंने कभी getObjectIdजेएस में मानक के भाग के रूप में ऐसा कुछ भी देखा है )। नक्शे भी आदेश के संरक्षण की गारंटी देते हैं इसलिए सभी संरक्षण के लिए बेहतर हैं और कभी-कभी आपको कुछ प्रकार करने की आवश्यकता से बचा सकते हैं।

मानचित्र और वस्तुओं के बीच व्यवहार में कई पेशेवरों और विपक्ष हैं। ऑब्जेक्ट्स फायदे और नुकसान दोनों को बहुत मजबूती से जावास्क्रिप्ट के मूल में एकीकृत करते हैं जो उन्हें महत्वपूर्ण समर्थन में अंतर से परे महत्वपूर्ण मानचित्र से अलग करता है।

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

({}).toString
    toString() { [native code] }
JSON.parse('{}').toString
    toString() { [native code] }
(Object.create(null)).toString
    undefined
JSON.parse('{}', (k,v) => (typeof v === 'object' && Object.setPrototypeOf(v, null) ,v)).toString
    undefined

वस्तुओं पर प्रदूषण न केवल कुछ ऐसा है जो कोड को अधिक कष्टप्रद, धीमा, आदि बनाता है, बल्कि सुरक्षा के लिए संभावित परिणाम भी हो सकता है।

ऑब्जेक्ट शुद्ध हैश टेबल नहीं हैं, लेकिन अधिक करने की कोशिश कर रहे हैं। आपके पास सिरदर्द है जैसे hasOwnProperty, लंबाई आसानी से प्राप्त नहीं कर पाना ( Object.keys(obj).length) इत्यादि। ऑब्जेक्ट्स को विशुद्ध रूप से हैश मैप्स के रूप में उपयोग नहीं किया जाता है, लेकिन गतिशील एक्स्टेंसिबल ऑब्जेक्ट्स के रूप में अच्छी तरह से और इसलिए जब आप उन्हें शुद्ध हैश तालिकाओं के रूप में उपयोग करते हैं तो समस्याएं पैदा होती हैं।

विभिन्न आम कार्यों की तुलना / सूची:

    Object:
       var o = {};
       var o = Object.create(null);
       o.key = 1;
       o.key += 10;
       for(let k in o) o[k]++;
       var sum = 0;
       for(let v of Object.values(m)) sum += v;
       if('key' in o);
       if(o.hasOwnProperty('key'));
       delete(o.key);
       Object.keys(o).length
    Map:
       var m = new Map();
       m.set('key', 1);
       m.set('key', m.get('key') + 10);
       m.foreach((k, v) => m.set(k, m.get(k) + 1));
       for(let k of m.keys()) m.set(k, m.get(k) + 1);
       var sum = 0;
       for(let v of m.values()) sum += v;
       if(m.has('key'));
       m.delete('key');
       m.size();

अलग-अलग उतार-चढ़ाव (प्रदर्शन, प्रवृत्ति, पोर्टेबल, विस्तार योग्य, आदि) के साथ कुछ अन्य विकल्प, दृष्टिकोण, कार्यप्रणाली आदि हैं। ऑब्जेक्ट भाषा के लिए थोड़ा अजीब हैं, इसलिए आपके पास उनके साथ काम करने के लिए बहुत सारे स्टैटिक तरीके हैं।

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

मैप्स के लिए एक पर्याप्त नुकसान यह है कि वे सीधे JSON के साथ समर्थित नहीं हैं। पार्सिंग संभव है लेकिन कई हैंगअप हैं:

JSON.parse(str, (k,v) => {
    if(typeof v !== 'object') return v;
    let m = new Map();
    for(k in v) m.set(k, v[k]);
    return m;
});

उपरोक्त एक गंभीर प्रदर्शन हिट पेश करेगा और किसी भी स्ट्रिंग कुंजी का समर्थन नहीं करेगा। JSON एन्कोडिंग और भी कठिन और समस्याग्रस्त है (यह कई दृष्टिकोणों में से एक है):

// An alternative to this it to use a replacer in JSON.stringify.
Map.prototype.toJSON = function() {
    return JSON.stringify({
        keys: Array.from(this.keys()),
        values: Array.from(this.values())
    });
};

यह इतना बुरा नहीं है यदि आप विशुद्ध रूप से मैप्स का उपयोग कर रहे हैं, लेकिन समस्याएँ होंगी जब आप प्रकारों का मिश्रण कर रहे हैं या गैर-स्केलर मानों को कुंजियों के रूप में उपयोग कर रहे हैं (यह नहीं कि JSON उस तरह के मुद्दे के साथ एकदम सही है जैसा कि यह है, IE परिपत्र ऑब्जेक्ट संदर्भ)। मैंने इसका परीक्षण नहीं किया है, लेकिन संभावना है कि यह कठोर होने की तुलना में प्रदर्शन को बुरी तरह प्रभावित करेगा।

अन्य स्क्रिप्टिंग भाषाओं में अक्सर ऐसी समस्याएं नहीं होती हैं क्योंकि उनके पास मैप, ऑब्जेक्ट और एरे के लिए स्पष्ट रूप से गैर-स्केलर प्रकार होते हैं। वेब विकास अक्सर गैर-स्केलर प्रकारों के साथ एक दर्द होता है जहां आपको PHP मर्ज एरे / मैप जैसी चीजों से निपटना पड़ता है, ऑब्जेक्ट के लिए ए / एम का उपयोग करते हुए ऑब्जेक्ट और जेएस मर्ज / एरे के साथ मैप / ऑब्जेक्ट का विस्तार करता है। जटिल प्रकारों को विलय करना उच्च स्तरीय स्क्रिप्टिंग भाषाओं के शैतान का प्रतिबंध है।

अब तक ये काफी हद तक कार्यान्वयन के इर्द-गिर्द हैं, लेकिन बुनियादी कार्यों के लिए प्रदर्शन भी महत्वपूर्ण है। प्रदर्शन भी जटिल है क्योंकि यह इंजन और उपयोग पर निर्भर करता है। नमक के एक दाने के साथ मेरे परीक्षण करें क्योंकि मैं किसी भी गलती से इंकार नहीं कर सकता (मुझे इसे जल्दी करना है)। आपको अपना परीक्षण चलाने के लिए पुष्टि करनी चाहिए कि मेरा केवल एक विशिष्ट संकेत देने के लिए केवल विशिष्ट विशिष्ट परिदृश्यों की जांच करें। क्रोम में बहुत बड़ी वस्तुओं / नक्शों के परीक्षणों के अनुसार वस्तुओं का प्रदर्शन नष्ट होने के कारण खराब होता है, जो जाहिर तौर पर किसी भी तरह ओ (1) के बजाय चाबियों की संख्या के अनुपात में होता है:

Object Set Took: 146
Object Update Took: 7
Object Get Took: 4
Object Delete Took: 8239
Map Set Took: 80
Map Update Took: 51
Map Get Took: 40
Map Delete Took: 2

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

इस विशेष बेंचमार्क के लिए फ़ायरफ़ॉक्स में यह एक अलग कहानी है:

Object Set Took: 435
Object Update Took: 126
Object Get Took: 50
Object Delete Took: 2
Map Set Took: 63
Map Update Took: 59
Map Get Took: 33
Map Delete Took: 1

मुझे तुरंत इस बात पर ध्यान देना चाहिए कि फ़ायरफ़ॉक्स में वस्तुओं से हटाने वाले इस विशेष बेंचमार्क में कोई समस्या नहीं है, हालाँकि अन्य बेंचमार्क में यह विशेष रूप से तब समस्या उत्पन्न करता है जब क्रोम की तरह ही कई कुंजियाँ होती हैं। बड़े संग्रह के लिए फ़ायरफ़ॉक्स में मानचित्र स्पष्ट रूप से बेहतर हैं।

हालांकि यह कहानी का अंत नहीं है, कई छोटी वस्तुओं या मानचित्रों के बारे में क्या? मैंने इसका एक त्वरित बेंचमार्क किया है, लेकिन एक संपूर्ण (सेटिंग / प्राप्त करने वाला) नहीं है, जो उपरोक्त संचालन में कम संख्या में कुंजी के साथ सर्वश्रेष्ठ प्रदर्शन करता है। यह परीक्षण स्मृति और आरंभीकरण के बारे में अधिक है।

Map Create: 69    // new Map
Object Create: 34 // {}

फिर से ये आंकड़े अलग-अलग हैं, लेकिन मूल रूप से ऑब्जेक्ट का एक अच्छा नेतृत्व है। कुछ मामलों में नक्शों पर वस्तुओं की बढ़त चरम (~ 10 गुना बेहतर) है लेकिन औसतन यह लगभग 2-3 गुना बेहतर है। ऐसा लगता है कि चरम प्रदर्शन स्पाइक्स दोनों तरीकों से काम कर सकते हैं। मैंने इसे केवल क्रोम और निर्माण में मेमोरी मेमोरी उपयोग और ओवरहेड में परीक्षण किया। मुझे यह देखकर काफी आश्चर्य हुआ कि क्रोम में यह प्रतीत होता है कि एक कुंजी के साथ मैप्स एक कुंजी के साथ ऑब्जेक्ट की तुलना में लगभग 30 गुना अधिक मेमोरी का उपयोग करते हैं।

उपरोक्त सभी कार्यों (4 कुंजी) के साथ कई छोटी वस्तुओं के परीक्षण के लिए:

Chrome Object Took: 61
Chrome Map Took: 67
Firefox Object Took: 54
Firefox Map Took: 139

स्मृति आबंटन के संदर्भ में ये मुक्त / जीसी के संदर्भ में समान हैं लेकिन मानचित्र ने 5 गुना अधिक मेमोरी का उपयोग किया है। इस परीक्षण में 4 कुंजियों का उपयोग किया गया था, जहां अंतिम परीक्षा में मैंने केवल एक कुंजी सेट की थी ताकि यह मेमोरी ओवरहेड में कमी को समझा सके। मैंने इस परीक्षण को कुछ बार चलाया और समग्र गति के संदर्भ में मानचित्र के लिए मैप / ऑब्जेक्ट अधिक या कम गर्दन और गर्दन हैं। छोटी वस्तुओं के लिए फ़ायरफ़ॉक्स में कुल मिलाकर नक्शों पर एक निश्चित प्रदर्शन लाभ है।

इस कोर्स में व्यक्तिगत विकल्प शामिल नहीं हैं जो बेतहाशा भिन्न हो सकते हैं। मैं इन आंकड़ों के साथ सूक्ष्म अनुकूलन की सलाह नहीं दूंगा। आप इस से बाहर निकल सकते हैं कि अंगूठे के एक नियम के रूप में, बहुत बड़े कुंजी मूल्य स्टोर और छोटे कुंजी मूल्य स्टोर के लिए ऑब्जेक्ट के लिए मैप्स पर अधिक दृढ़ता से विचार करें।

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


क्रमबद्धता की कमी कई डेवलपर्स के लिए एक वास्तविक दर्द रही है। के वोट दें को देखो मैं LocalStorage में एक ES6 मानचित्र कैसे जारी रहती है (या कहीं और)? और आप JSON.string को ES6 मैप कैसे बनाते हैं?
फ्रैंकलिन यू

क्या मिलिसेकंड, बाइट्स या कुल वस्तुओं में संख्या है?
स्टेफन्सआरी

इतना लिया एमएस (कुछ लिया कुछ कहने के लिए कम है, इसलिए यह इस मामले में समय का उपयोग करता है)। हालांकि यह एक पुराना परीक्षण है और मेरे पास अब बेंचमार्क कोड नहीं है। यह शायद अब बहुत अलग है। उदाहरण के लिए डिलीट इश्यू मुझे विश्वास है कि निश्चित है।
jgmjgm

27

मुझे नहीं लगता कि अब तक के उत्तरों में निम्नलिखित बिंदुओं का उल्लेख किया गया है, और मुझे लगा कि वे उल्लेख के लायक होंगे।


नक्शे बड़े हो सकते हैं

क्रोम में मैं एक नियमित वस्तु के साथ बनाम 11.1 मिलियन के साथ 16.7 मिलियन कुंजी / मूल्य जोड़े प्राप्त कर सकता हूं । एक के साथ लगभग 50% अधिक जोड़े । दुर्घटनाग्रस्त होने से पहले वे दोनों लगभग 2GB मेमोरी लेते हैं, और इसलिए मुझे लगता है कि क्रोम द्वारा मेमोरी लिमिटिंग के साथ किया जा सकता है ( संपादित करें : हां, 2 भरने की कोशिश करें और क्रैश होने से पहले आपको केवल 8.3 मिलियन जोड़े मिलते हैं)। आप इसे स्वयं इस कोड के साथ परीक्षण कर सकते हैं (उन्हें अलग-अलग चलाएं और एक ही समय में नहीं, जाहिर है):MapMapMaps

var m = new Map();
var i = 0;
while(1) {
    m.set(((10**30)*Math.random()).toString(36), ((10**30)*Math.random()).toString(36));
    i++;
    if(i%1000 === 0) { console.log(i/1000,"thousand") }
}
// versus:
var m = {};
var i = 0;
while(1) {
    m[((10**30)*Math.random()).toString(36)] = ((10**30)*Math.random()).toString(36);
    i++;
    if(i%1000 === 0) { console.log(i/1000,"thousand") }
}

ऑब्जेक्ट में कुछ गुण / कुंजियाँ पहले से हैं

इस एक ने मुझे पहले फँसाया है। नियमित रूप से वस्तुओं है toString, constructor, valueOf, hasOwnProperty, isPrototypeOfऔर अन्य पूर्व मौजूदा गुण का एक समूह। यह ज्यादातर उपयोग के मामलों के लिए एक बड़ी समस्या नहीं हो सकती है, लेकिन इससे पहले मेरे लिए समस्याएं पैदा हुई हैं।

नक्शे धीमे हो सकते हैं:

के कारण .getसमारोह कॉल उपरि और आंतरिक अनुकूलन की कमी, मानचित्र में काफी धीमी हो सकता है कुछ कार्यों के लिए एक सादे पुराने जावास्क्रिप्ट वस्तु से।


1
आपकी राय में, क्या शब्दार्थ यहां प्रदर्शन से आगे निकल जाते हैं? यदि आपको एक डिक्शनरी की आवश्यकता है, तो मानचित्र सही लगता है, लेकिन धीमी लुक को स्वीकार करना कठिन है। क्या शब्दकोशों का पूरा बिंदु एक तेज़ खोज नहीं है?
user2954463

3
यदि आप 11 मिलियन की / वैल्यू पेयर के साथ ठीक हैं, तो मैं निश्चित रूप से सादे पुरानी वस्तुओं के साथ जाऊँगा, और पहले से मौजूद कुंजियों toString, जैसे constructor, आदि के बारे में परवाह नहीं करता (यानी आपकी कुंजी उनके साथ टकराने की संभावना नहीं है)। जैसे वेतन वृद्धि है - वे के साथ काम करने के लिए आसान कर रहे हैं obj[i] = (obj[i] || 0) + 1, जबकि साथ Mapयह map.set(i, (map.get(i) || 0) + 1)अभी भी बहुत बुरा नहीं है जो, लेकिन यह सिर्फ शो कैसे चीजें बेकार में गंदा हो सकता है। मैप्स में निश्चित रूप से उनके उपयोग के मामले हैं, लेकिन अक्सर एक सादा वस्तु क्या करेगी।

1
ध्यान दें कि आप डिफ़ॉल्ट से छुटकारा पा सकते toString, constructorलिख कर, (आदि) वस्तु गुण obj = Object.create(null)के बजाय obj = {}

18

ऑब्जेक्ट्स शब्दकोशों की तरह व्यवहार कर सकते हैं क्योंकि जावास्क्रिप्ट गतिशील रूप से टाइप किया गया है, जिससे आप किसी भी समय किसी ऑब्जेक्ट पर गुण जोड़ या निकाल सकते हैं।

लेकिन नई Map()कार्यक्षमता बहुत बेहतर है क्योंकि:

  • यह प्रदान करता है get, set, has, और deleteतरीकों।
  • केवल तार के बजाय कुंजियों के लिए किसी भी प्रकार को स्वीकार करता है।
  • आसान for-ofउपयोग के लिए एक पुनरावृत्ति प्रदान करता है और परिणामों के क्रम को बनाए रखता है।
  • प्रोटोटाइप या प्रतिलिपि बनाने के दौरान दिखाए जाने वाले प्रोटोटाइप और अन्य गुणों के साथ किनारे के मामले नहीं होते हैं।
  • यह लाखों वस्तुओं का समर्थन करता है।
  • बहुत तेज है और तेज हो रही है क्योंकि जावास्क्रिप्ट इंजन बेहतर हो जाते हैं।

99% समय आपको बस एक का उपयोग करना चाहिए Map()। हालाँकि यदि आप केवल स्ट्रिंग-आधारित कुंजियों का उपयोग कर रहे हैं और अधिकतम पठन प्रदर्शन की आवश्यकता है, तो ऑब्जेक्ट एक बेहतर विकल्प हो सकते हैं।

विस्तार यह है कि (लगभग सभी) जावास्क्रिप्ट इंजन पृष्ठभूमि में C ++ कक्षाओं के लिए वस्तुओं को संकलित करते हैं। इन प्रकारों को उनके "आउटलाइन" द्वारा कैश और पुन: उपयोग किया जाता है, इसलिए जब आप समान सटीक गुणों के साथ एक नई वस्तु बनाते हैं तो इंजन एक मौजूदा पृष्ठभूमि वर्ग का पुन: उपयोग करेगा। इन वर्गों पर गुणों के लिए पहुँच पथ बहुत अनुकूलित है और लुकअप की तुलना में बहुत तेज़ है Map()

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

इसलिए अगर आपके पास स्ट्रिंग कीज़ के साथ राइट-रीड-हैवी वर्कलोड है तो objectएक विशेष हाई-परफॉर्मेंस डिक्शनरी के रूप में उपयोग करें , लेकिन हर चीज के लिए ए का उपयोग करें Map()


वस्तु प्रदान करता है get set has deleteआदि कार्यक्षमता भी, यह सिर्फ इतना सुंदर नहीं है (लेकिन या तो बुरा नहीं है)। किस तरीके से Mapपुनरावृत्ति के लिए उपयोग करना आसान है? यकीन नहीं होता कि मैं सहमत हो सकता हूं।
एंड्रयू

@ और मैं उन तरीकों के बारे में ले रहा हूं, और जो आप उपयोग कर रहे हैं और परिणाम के आधार पर कार्यक्षमता अलग है। Iterating आसान है क्योंकि प्रोटोटाइप और देशी गुण लूप में दिखाई नहीं देते हैं और एक सामान्य JS itter का उपयोग करते हैं जो समान क्रम बनाए रखता है।
मणि गंधम

11

अन्य उत्तरों के अलावा, मैंने पाया है कि मैप्स वस्तुओं की तुलना में अधिक अस्पष्ट और क्रियात्मक हैं।

obj[key] += x
// vs.
map.set(map.get(key) + x)

यह महत्वपूर्ण है, क्योंकि कम कोड पढ़ने के लिए तेज़ है, अधिक सीधे अभिव्यंजक है, और प्रोग्रामर के सिर में बेहतर रखा गया है

एक और पहलू: क्योंकि सेट () मैप लौटाता है, मूल्य नहीं, यह चेन असाइनमेंट के लिए असंभव है।

foo = obj[key] = x;  // Does what you expect
foo = map.set(key, x)  // foo !== x; foo === map

नक्शे को डीबग करना भी अधिक दर्दनाक है। नीचे, आप वास्तव में यह नहीं देख सकते हैं कि नक्शे में क्या चाबियाँ हैं। आपको ऐसा करने के लिए कोड लिखना होगा।

सौभाग्य एक मैप Iterator का मूल्यांकन

वस्तुओं का मूल्यांकन किसी भी आईडीई द्वारा किया जा सकता है:

किसी ऑब्जेक्ट का मूल्यांकन करने वाला WebStorm


4
यह सब देखते हुए, ऐसा लगता है जैसे नक्शा एक समय से पहले का अनुकूलन है।
PRMan

10

सारांश:

  • Object: एक डेटा संरचना जिसमें डेटा को मुख्य मूल्य जोड़े के रूप में संग्रहीत किया जाता है। किसी ऑब्जेक्ट में कुंजी को एक संख्या, स्ट्रिंग या प्रतीक होना चाहिए। मूल्य कुछ भी हो सकता है इसलिए अन्य ऑब्जेक्ट्स, फ़ंक्शन आदि। एक ऑब्जेक्ट एक गैर-ऑर्डर की गई डेटा संरचना है, अर्थात मुख्य मूल्य जोड़े के सम्मिलन का क्रम याद नहीं है।
  • ES6 Map: एक डेटा संरचना जिसमें डेटा को मुख्य मूल्य जोड़े के रूप में संग्रहीत किया जाता है। जिसमें एक मूल्य के लिए एक अद्वितीय कुंजी नक्शे । कुंजी और मान दोनों किसी भी डेटा प्रकार में हो सकते हैं । नक्शा एक पुनरावृत्त डेटा संरचना है, इसका मतलब है कि सम्मिलन के अनुक्रम को याद किया जाता है और हम तत्वों को उदाहरण के for..ofलूप में एक्सेस कर सकते हैं।

मुख्य अंतर:

  • A Mapका आदेश दिया गया है और चलने योग्य है, जबकि कोई ऑब्जेक्ट ऑर्डर नहीं किया गया है और न ही चलने योग्य है

  • हम किसी भी प्रकार के डेटा को एक Mapकुंजी के रूप में रख सकते हैं , जबकि ऑब्जेक्ट में केवल एक कुंजी के रूप में एक संख्या, स्ट्रिंग या प्रतीक हो सकते हैं।

  • एक Mapinherits से Map.prototype। यह सभी प्रकार के उपयोगिता कार्य और गुण प्रदान करता है जो Mapवस्तुओं के साथ काम करना बहुत आसान बनाता है।

उदाहरण:

वस्तु:

let obj = {};

// adding properties to a object
obj.prop1 = 1;
obj[2]    =  2;

// getting nr of properties of the object
console.log(Object.keys(obj).length)

// deleting a property
delete obj[2]

console.log(obj)

नक्शा:

const myMap = new Map();

const keyString = 'a string',
    keyObj = {},
    keyFunc = function() {};

// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, 'value associated with keyObj');
myMap.set(keyFunc, 'value associated with keyFunc');

console.log(myMap.size); // 3

// getting the values
console.log(myMap.get(keyString));    // "value associated with 'a string'"
console.log(myMap.get(keyObj));       // "value associated with keyObj"
console.log(myMap.get(keyFunc));      // "value associated with keyFunc"

console.log(myMap.get('a string'));   // "value associated with 'a string'"
                         // because keyString === 'a string'
console.log(myMap.get({}));           // undefined, because keyObj !== {}
console.log(myMap.get(function() {})) // undefined, because keyFunc !== function () {}

स्रोत: एमडीएन


4

इसके अलावा एक अच्छी तरह से परिभाषित क्रम में चलने योग्य होने के नाते, और चाबी के अलावा मनमाने मूल्यों का उपयोग करने की क्षमता (अपवादों को छोड़कर -0), नक्शे निम्नलिखित कारणों से उपयोगी हो सकते हैं:

  • युक्ति औसत रूप से मानचित्र संचालन को लागू करती है।

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

  • वस्तुओं में अप्रत्याशित अप्रत्याशित व्यवहार हो सकते हैं।

    उदाहरण के लिए, मान लें कि आपने कोई भी fooसंपत्ति किसी नई बनाई गई वस्तु पर सेट नहीं की है obj, इसलिए आप obj.fooअपरिभाषित लौटने की उम्मीद करते हैं। लेकिन fooअंतर्निहित संपत्ति से प्राप्त किया जा सकता है Object.prototype। या आप obj.fooएक असाइनमेंट का उपयोग करके बनाने का प्रयास करते हैं , लेकिन कुछ सेटर Object.prototypeआपके मूल्य को संग्रहीत करने के बजाय चलाता है।

    मैप्स इस तरह की चीजों को रोकते हैं। खैर, जब तक कुछ स्क्रिप्ट के साथ गड़बड़ नहीं होती Map.prototype। और Object.create(null)काम भी करेगा, लेकिन फिर आप साधारण ऑब्जेक्ट इनिशियलाइज़र सिंटैक्स खो देते हैं।


4

सादे जावास्क्रिप्ट ऑब्जेक्ट्स के बजाय मैप्स का उपयोग कब करें?

सादा जावास्क्रिप्ट ऑब्जेक्ट {key: 'value'} संरचित डेटा रखता है। लेकिन सादे JS ऑब्जेक्ट की अपनी सीमाएँ हैं:

  1. केवल तार और प्रतीकों का उपयोग वस्तुओं की कुंजी के रूप में किया जा सकता है। यदि हम किसी अन्य चीज़ों का उपयोग करते हैं, तो एक वस्तु की कुंजी के रूप में संख्याएँ, फिर उन कुंजियों तक पहुँचने के दौरान हम देखेंगे कि उन कुंजियों को तारों में बदल दिया जाएगा, जिससे हमें प्रकार की निरंतरता खोनी पड़ेगी। const नाम = {1: 'एक', 2: 'दो'}; Object.keys (नाम); // ['1', '2']

  2. जेएस पहचानकर्ताओं को किसी वस्तु के प्रमुख नामों (जैसे, स्ट्रिंग, कंस्ट्रक्टर आदि) के रूप में लिखकर प्रोटोटाइप से विरासत में मिली संपत्तियों को गलती से अधिलेखित करने की संभावना है।

  3. किसी अन्य वस्तु का उपयोग किसी वस्तु की कुंजी के रूप में नहीं किया जा सकता है, इसलिए किसी वस्तु के लिए कोई अतिरिक्त जानकारी नहीं लिखी जा सकती है, उस वस्तु को किसी अन्य वस्तु की कुंजी के रूप में लिखा जा सकता है और किसी अन्य वस्तु के मूल्य में अतिरिक्त जानकारी होगी।

  4. ऑब्जेक्ट पुनरावृत्त नहीं हैं

  5. किसी वस्तु का आकार सीधे निर्धारित नहीं किया जा सकता है

ऑब्जेक्ट्स की ये सीमाएँ मैप्स द्वारा हल की जाती हैं, लेकिन हमें मैप्स को प्रतिस्थापन के बजाय ऑब्जेक्ट्स के पूरक के रूप में समझना चाहिए। मूल रूप से मानचित्र केवल सारणियों का सरणी है, लेकिन हमें मानचित्र ऑब्जेक्ट के लिए सारणियों के सरणी को नए कीवर्ड के साथ तर्क के रूप में पास करना होगा अन्यथा केवल सरणी के सरणी के लिए मानचित्र के उपयोगी गुण और तरीके उपलब्ध नहीं हैं। और याद रखें कि एरे के सरणी के अंदर की-वैल्यू जोड़े या मैप केवल कॉमा द्वारा अलग किए जाने चाहिए, सादे वस्तुओं में कोई कॉलोन की तरह नहीं।

मानचित्र या ऑब्जेक्ट का उपयोग करने के लिए 3 युक्तियां तय करने के लिए:

  1. ऑब्जेक्ट्स पर मैप्स का उपयोग करें जब कुंजियाँ अज्ञात समय तक चलती हैं क्योंकि उपयोगकर्ता इनपुट या अनजाने में बनाई गई कुंजी उस कोड को तोड़ सकती है जो ऑब्जेक्ट का उपयोग करता है यदि वे कुंजी ऑब्जेक्ट के विरासत वाले गुणों को अधिलेखित करते हैं, तो मैप उन मामलों में सुरक्षित है। जब सभी कुंजियाँ एक ही प्रकार की हों और सभी मानचित्र एक ही प्रकार के हों तो भी मानचित्रों का उपयोग करें।

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

  3. यदि हमें व्यक्तिगत तत्वों पर काम करने की आवश्यकता हो तो वस्तुओं का उपयोग करें।

मैप्स का उपयोग करने के लाभ हैं:

1. नक्शा किसी भी कुंजी प्रकार को स्वीकार करता है और कुंजी के प्रकार को संरक्षित करता है:

हम जानते हैं कि यदि वस्तु की कुंजी एक स्ट्रिंग या प्रतीक नहीं है, तो JS संक्षेप में इसे एक स्ट्रिंग में बदल देता है। इसके विपरीत, मानचित्र किसी भी प्रकार की कुंजियों को स्वीकार करता है: स्ट्रिंग, संख्या, बूलियन, प्रतीक आदि और मानचित्र मूल कुंजी प्रकार को संरक्षित करता है। यहां हम मैप के अंदर नंबर का उपयोग कुंजी के रूप में करेंगे और यह एक नंबर रहेगा:

const numbersMap= new Map();

numbersMap.set(1, 'one');

numbersMap.set(2, 'two');

const keysOfMap= [...numbersMap.keys()];

console.log(keysOfMap);                        // [1, 2]

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

const foo= {name: foo};

const bar= {name: bar};

const kindOfMap= [[foo, 'Foo related data'], [bar, 'Bar related data']];

लेकिन इस दृष्टिकोण का नकारात्मक पक्ष मूल्य द्वारा पहुंच की जटिलता है, क्योंकि हमें वांछित मूल्य प्राप्त करने के लिए पूरे सरणी के माध्यम से लूप करना पड़ता है।

function getBy Key(kindOfMap, key) {
    for (const [k, v]  of kindOfMap) {
        if(key === k) {
            return v;
        }
    }
    return undefined;
}

getByKey(kindOfMap, foo);            // 'Foo related data'

हम उचित मानचित्र का उपयोग करके मूल्य तक सीधी पहुंच नहीं होने की इस समस्या को हल कर सकते हैं।

const foo= {name: 'foo'};

const bar= {name: 'bar'};

const myMap= new Map();

myMap.set(foo, 'Foo related data');
myMap.set(bar, 'Bar related data');

console.log(myMap.get(foo));            // 'Foo related data'

हम WeakMap का उपयोग करके ऐसा कर सकते थे, बस लिखना होगा, const myMap = new WeakMap ()। मैप और वीकएप के बीच अंतर यह है कि वीकपाइप कुंजी (यहां वस्तुओं) के कचरा संग्रह के लिए अनुमति देता है, इसलिए यह मेमोरी लीक को रोकता है, वीकपाइप केवल ऑब्जेक्ट्स को कुंजी के रूप में स्वीकार करता है, और वीकैप ने तरीकों का सेट कम कर दिया है।

2. मुख्य नामों पर मानचित्र का कोई प्रतिबंध नहीं है:

सादे जेएस वस्तुओं के लिए हम गलती से प्रोटोटाइप से विरासत में मिली संपत्ति को अधिलेखित कर सकते हैं और यह खतरनाक हो सकता है। यहाँ हम अभिनेता की संपत्ति () की संपत्ति को अधिलेखित करेंगे:

const actor= {
    name: 'Harrison Ford',
    toString: 'Actor: Harrison Ford'
};

अब निर्धारित करते हैं कि एक fn .PlainObject () निर्धारित करता है कि आपूर्ति तर्क एक सादा वस्तु है और यह fn स्ट्रिंग का उपयोग करता है () इसे जांचने की विधि:

function isPlainObject(value) {
    return value.toString() === '[object Object]';
}

isPlainObject(actor);        // TypeError : value.toString is not a function

// this is because inside actor object toString property is a string instead of inherited method from prototype

मानचित्र में प्रमुख नामों पर कोई प्रतिबंध नहीं है, हम प्रमुख नामों का उपयोग कर सकते हैं जैसे किस्ट्रिंग, कंस्ट्रक्टर आदि। हालांकि एक्टरपॉइंट ऑब्जेक्ट में स्ट्रींग नाम की संपत्ति होती है, लेकिन एस्टरपॉइंट ऑब्जेक्ट के प्रोटोटाइप से विरासत में मिली विधि (toString) विरासत में मिलती है।

const actorMap= new Map();

actorMap.set('name', 'Harrison Ford');

actorMap.set('toString', 'Actor: Harrison Ford');

function isMap(value) {
  return value.toString() === '[object Map]';
}

console.log(isMap(actorMap));     // true

यदि हमारे पास एक ऐसी स्थिति है जहां उपयोगकर्ता इनपुट कुंजी बनाता है तो हमें एक सादे वस्तु के बजाय उन कुंजियों को मानचित्र के अंदर ले जाना चाहिए। ऐसा इसलिए है क्योंकि उपयोगकर्ता एक कस्टम फ़ील्ड नाम चुन सकता है, जैसे, स्ट्रींगर, कंस्ट्रक्टर इत्यादि तो एक सादे ऑब्जेक्ट में ऐसे प्रमुख नाम संभवतः उस कोड को तोड़ सकते हैं जो बाद में इस ऑब्जेक्ट का उपयोग करता है। तो सही समाधान उपयोगकर्ता इंटरफ़ेस स्थिति को एक नक्शे से बांधना है, मानचित्र को तोड़ने का कोई तरीका नहीं है:

const userCustomFieldsMap= new Map([['color', 'blue'], ['size', 'medium'], ['toString', 'A blue box']]);

3. नक्शा चलने योग्य है:

एक सादे वस्तु के गुणों को पुनरावृत्त करने के लिए हमें Object.entries () या Object.keys () की आवश्यकता होती है। Object.entries (plainObject) ऑब्जेक्ट से निकाले गए प्रमुख मूल्य जोड़े की एक सरणी देता है, हम तब उन कुंजियों और मूल्यों को नष्ट कर सकते हैं और सामान्य कुंजी और मान आउटपुट प्राप्त कर सकते हैं।

const colorHex= {
  'white': '#FFFFFF',
  'black': '#000000'
}

for(const [color, hex] of Object.entries(colorHex)) {
  console.log(color, hex);
}
//
'white' '#FFFFFF'   
'black' '#000000'

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

const colorHexMap= new Map();
colorHexMap.set('white', '#FFFFFF');
colorHexMap.set('black', '#000000');


for(const [color, hex] of colorHexMap) {
  console.log(color, hex);
}
//'white' '#FFFFFF'   'black' '#000000'

इसके अलावा map.keys () कुंजियों के ऊपर एक पुनरावृत्ति देता है और map.values ​​() मानों पर एक पुनरावृत्ति देता है।

4. हम आसानी से एक मानचित्र का आकार जान सकते हैं

हम सीधे सादे ऑब्जेक्ट में गुणों की संख्या निर्धारित नहीं कर सकते हैं। हमें एक सहायक fn की आवश्यकता है जैसे, Object.keys () जो ऑब्जेक्ट की कुंजियों के साथ एक सरणी देता है फिर लंबाई संपत्ति का उपयोग करके हम कुंजियों की संख्या या सादे ऑब्जेक्ट का आकार प्राप्त कर सकते हैं।

const exams= {'John Rambo': '80%', 'James Bond': '60%'};

const sizeOfObj= Object.keys(exams).length;

console.log(sizeOfObj);       // 2

लेकिन मैप्स के मामले में हम map.size प्रॉपर्टी का उपयोग करके मैप के आकार तक सीधी पहुंच बना सकते हैं।

const examsMap= new Map([['John Rambo', '80%'], ['James Bond', '60%']]);

console.log(examsMap.size);

1

मैप या ऑब्जेक्ट का उपयोग करने के लिए ये दो सुझाव आपको यह तय करने में मदद कर सकते हैं:

  • जब समय चल रहा हो तब तक कुंजियाँ अज्ञात हों, और जब सभी कुंजियाँ एक ही प्रकार की हों और सभी मान एक ही प्रकार के हों, तब मानचित्रों का उपयोग करें।

  • अगर कोई आदिम मानों को कुंजी के रूप में संग्रहीत करने की आवश्यकता है तो मामले में नक्शे का उपयोग करें क्योंकि ऑब्जेक्ट प्रत्येक कुंजी को एक स्ट्रिंग के रूप में मानता है या तो एक संख्या मान, बूलियन मूल्य या किसी अन्य आदिम मूल्य।

  • ऑब्जेक्ट का उपयोग तब करें जब व्यक्तिगत तत्वों पर काम करने वाले तर्क हों।

स्रोत: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Keyed_Collections#Object_and_Map_compared


2
ये युक्तियां विशेष रूप से उपयोगी नहीं लगती हैं, क्योंकि यह उन मानदंडों से चीजों को विभाजित करना आसान नहीं है। मैं पहले एक के साथ नहीं मिलता, क्यों नक्शे एक लाभ है जब चाबियाँ / मान एक ही प्रकार हैं। यह अधिक लगता है जैसे यह कहने की कोशिश कर रहा है कि कक्षाओं / संरचनाओं जैसी वस्तुओं का उपयोग करें, संग्रह जैसे नक्शे। दूसरे को लिखा जाता है कि वह खराब नहीं है। यह वास्तव में नक्शे का उपयोग करता है जब आपके पास मिश्रित स्ट्रिंग प्रकार ("1" और 1) होते हैं या जब आपको आवश्यक प्रकारों को संरक्षित करना होता है। आखिरी मुझे लगता है कि यह पहले जैसा है, यह मान रहा है कि आप नहीं जानते कि कोई वस्तु क्या है इसलिए यह अस्पष्ट है।
jgmjgm

1

यह मुझे याद रखने का एक छोटा तरीका है: केओआई

  1. चांबियाँ। ऑब्जेक्ट कुंजी तार या प्रतीक है। मैप कीज़ भी संख्याएँ हो सकती हैं (1 और "1" अलग हैं), ऑब्जेक्ट्स NaN, आदि। यह ===एक अपवाद के साथ कुंजियों के बीच अंतर करने के लिए उपयोग करता है, NaN !== NaNलेकिन आप NaNएक कुंजी के रूप में उपयोग कर सकते हैं ।
  2. गण। सम्मिलन आदेश याद किया जाता है। तो [...map]या [...map.keys()]एक विशेष आदेश है।
  3. इंटरफेस। ऑब्जेक्ट: obj[key]या obj.a(कुछ भाषा में, []और []=वास्तव में इंटरफ़ेस का हिस्सा हैं)। मानचित्र है get(), set(), has(), delete()आदि ध्यान दें कि आप उपयोग कर सकते हैं map[123]लेकिन एक सादे जे एस वस्तु के रूप में उपयोग किया जाता है कि।

0

मोज़िला के अनुसार

उदाहरण के साथ संक्षिप्त रूप में जावास्क्रिप्ट में ऑब्जेक्ट बनाम मैप

ऑब्जेक्ट- डेटा के भंडारण के लिए की-वैल्यू पेयर का उपयोग करते हुए मानचित्र के समान अवधारणा का अनुसरण करता है। लेकिन मामूली अंतर हैं जो कुछ स्थितियों में नक्शे को बेहतर प्रदर्शन करते हैं।

मानचित्र- एक डेटा संरचना है जो जोड़े के रूप में डेटा को संग्रहीत करने में मदद करता है। इस जोड़ी में एक अद्वितीय कुंजी और मान के लिए मैप की गई कुंजी होती है। यह नकल को रोकने में मदद करता है।

मुख्य अंतर

  • मानचित्र एक वस्तु का एक उदाहरण है लेकिन इसके विपरीत सत्य नहीं है।

var map = new Map();
var obj = new Object(); 
console.log(obj instanceof Map);   // false
console.log(map instanceof Object);  // true

  • ऑब्जेक्ट में, कुंजी-फ़ील्ड का डेटा-प्रकार पूर्णांक, स्ट्रिंग्स और प्रतीकों तक सीमित है। जबकि मानचित्र में, की-फ़ील्ड किसी भी प्रकार का डेटा-प्रकार (पूर्णांक, एक सरणी, एक ऑब्जेक्ट) हो सकता है

var map = new Map();//Empty 
map.set(1,'1');
map.set('one', 1);
map.set('{}', {name:'Hello world'});
map.set(12.3, 12.3)
map.set([12],[12345])

for(let [key,value] of map.entries())
  console.log(key+'---'+value)

  • मानचित्र में, तत्वों का मूल क्रम संरक्षित है। वस्तुओं के मामले में यह सही नहीं है।

let obj ={
  1:'1',
  'one':1,
  '{}': {name:'Hello world'},
  12.3:12.3,
  [12]:[100]
}
console.log(obj)


0

मैं this postमिंको गेचेव द्वारा सामने आया, जो प्रमुख अंतरों को स्पष्ट रूप से बताता है।

यहां छवि विवरण दर्ज करें

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