खोज रहे हैं इस और इस MDN पृष्ठों यह मैप्स और WeakMaps के बीच फर्क सिर्फ इतना है की तरह लगता है WeakMaps के लिए एक लापता "आकार" संपत्ति है। लेकिन क्या यह सच है? उनमें क्या अंतर है?
key
एकत्र नहीं किया जा सकता, क्योंकि यह आपके द्वारा संदर्भित है।
key
एकत्र नहीं किया जा सकता, क्योंकि यह आपके द्वारा संदर्भित है।
जवाबों:
से बहुत ही पृष्ठ, अनुभाग " क्यों कमजोर मानचित्र? " :
अनुभवी जावास्क्रिप्ट प्रोग्रामर ध्यान देंगे कि यह एपीआई 4 एपीआई विधियों द्वारा साझा किए गए दो सरणियों (कुंजी के लिए एक, मूल्यों के लिए एक) के साथ जावास्क्रिप्ट में लागू किया जा सकता है। इस तरह के कार्यान्वयन में दो मुख्य असुविधाएँ होंगी। पहला एक O (n) खोज है (n मानचित्र में कुंजियों की संख्या होने के नाते)। दूसरा एक मेमोरी लीक मुद्दा है। मैन्युअल रूप से लिखित नक्शों के साथ, चाबियों का सरणी मुख्य वस्तुओं के संदर्भों को बनाए रखेगा, जिससे उन्हें एकत्र होने से रोका जा सके। मूल WeakMaps में, प्रमुख वस्तुओं के संदर्भ को "कमजोर रूप से" रखा जाता है , जिसका अर्थ है कि वे कचरा संग्रह को नहीं रोकते हैं यदि वस्तु का कोई अन्य संदर्भ नहीं होगा।
संदर्भ कमजोर होने के कारण, WeakMap कुंजियाँ गणना योग्य नहीं हैं (यानी आपको कुंजियों की सूची देने की कोई विधि नहीं है)। यदि वे थे, तो सूची गैर-नियतत्ववाद का परिचय देते हुए, कचरा संग्रहण की स्थिति पर निर्भर करेगी।
[और इसीलिए उनके पास भी कोई size
संपत्ति नहीं है ]
यदि आप चाबियों की एक सूची रखना चाहते हैं, तो आपको इसे स्वयं बनाए रखना चाहिए। वहाँ भी एक ECMAScript प्रस्ताव है जो सरल सेटों और मानचित्रों को पेश करने के उद्देश्य से है जो कमजोर संदर्भों का उपयोग नहीं करेंगे और गणना करने योग्य होंगे।
- जो होगा "सामान्य" Map
रों । एमडीएन में उल्लेख नहीं किया गया है, लेकिन सद्भाव प्रस्ताव में , उनके पास भी है items
, keys
और values
जनरेटर के तरीके और Iterator
इंटरफ़ेस को लागू करते हैं ।
new Map().get(x)
एक समान दिखने के समय के बारे में एक सादे वस्तु से एक संपत्ति पढ़ने के रूप में है?
WeakMap
अभी भी प्रविष्टियों की एक सरणी (या अन्य संग्रह) है, यह सिर्फ कचरा संग्रहकर्ता को बताता है कि वे कमजोर संदर्भ हैं ।
वे दोनों अलग-अलग व्यवहार करते हैं जब उनकी चाबियाँ / मूल्यों द्वारा संदर्भित कोई वस्तु हटा दी जाती है। नीचे दिए गए उदाहरण कोड लेते हैं:
var map = new Map();
var weakmap = new WeakMap();
(function(){
var a = {x: 12};
var b = {y: 12};
map.set(a, 1);
weakmap.set(b, 2);
})()
उपरोक्त IIFE को निष्पादित किया जाता है कोई रास्ता नहीं है जिसे हम संदर्भित कर सकते हैं {x: 12}
और {y: 12}
अब। कचरा इकट्ठा करने वाला आगे बढ़ता है और "बीकैप" से कुंजी बी पॉइंटर को हटाता है {y: 12}
और मेमोरी से भी निकालता है। लेकिन "मैप" के मामले में, कचरा संग्रहकर्ता "मैप" से एक पॉइंटर नहीं हटाता है {x: 12}
और मेमोरी से भी नहीं हटाता है।
सारांश: WeakMap कचरा संग्रहकर्ता को अपना कार्य करने की अनुमति देता है लेकिन मानचित्र नहीं।
संदर्भ: http://qnimate.com/difference-between-map-and-weakmap-in-javascript/
map.entries().next().value // [{x:12}, 1]
WeakMap
सकती हैं , जबकि केवल गैर-आदिम कुंजियाँ हो सकती हैं (कुंजियाँ या संख्याएँ या Symbol
कुंजियाँ, केवल सरणियाँ, ऑब्जेक्ट्स, अन्य मानचित्र, आदि)।
Map
में नहीं बल्किWeakMap
हो सकता है कि अगली व्याख्या किसी के लिए अधिक स्पष्ट हो।
var k1 = {a: 1};
var k2 = {b: 2};
var map = new Map();
var wm = new WeakMap();
map.set(k1, 'k1');
wm.set(k2, 'k2');
k1 = null;
map.forEach(function (val, key) {
console.log(key, val); // k1 {a: 1}
});
k2 = null;
wm.get(k2); // undefined
जैसा कि आप देखते हैं, k1
मेमोरी से की को हटाने के बाद भी हम इसे मैप के अंदर एक्सेस कर सकते हैं। उसी समय k2
WeakMap की कुंजी को हटाने से इसे wm
संदर्भ से भी हटा दिया जाता है।
यही कारण है कि WeakMap forEach की तरह शानदार तरीके नहीं है, क्योंकि WeakMap कुंजियों की सूची जैसी कोई चीज नहीं है, वे सिर्फ अन्य वस्तुओं के संदर्भ हैं।
forEach
, (key, val)
वास्तव में होना चाहिए(val, key)
एक और अंतर (स्रोत: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ):
WeakMaps की कुंजियाँ केवल ऑब्जेक्ट प्रकार की होती हैं। कुंजी के रूप में आदिम डेटा प्रकार की अनुमति नहीं है (जैसे एक प्रतीक एक कमजोर मानचित्र कुंजी नहीं हो सकता है)।
न ही एक स्ट्रिंग, संख्या, या बूलियन को एक WeakMap
कुंजी के रूप में इस्तेमाल किया जा सकता है । A कुंजी के लिए आदिम मानों का उपयोग Map
कर सकता है ।
w = new WeakMap;
w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key
m = new Map
m.set('a', 'b'); // Works
से Javascript.info
मैप - अगर हम किसी ऑब्जेक्ट को रेगुलर मैप में चाबी की तरह इस्तेमाल करते हैं, तो मैप मौजूद होने के बाद भी वह ऑब्जेक्ट मौजूद रहता है। यह स्मृति को घेरता है और कचरा एकत्र नहीं हो सकता है।
let john = { name: "John" };
let array = [ john ];
john = null; // overwrite the reference
// john is stored inside the array, so it won't be garbage-collected
// we can get it as array[0]
उसी के समान, यदि हम किसी वस्तु का उपयोग नियमित मानचित्र में कुंजी के रूप में करते हैं, तो जबकि मानचित्र मौजूद है, वह वस्तु भी मौजूद है। यह स्मृति को घेरता है और कचरा एकत्र नहीं हो सकता है
let john = { name: "John" };
let map = new Map();
map.set(john, "...");
john = null; // overwrite the reference
// john is stored inside the map,
// we can get it by using map.keys()
WeakMap - अब, यदि हम इसमें एक कुंजी के रूप में किसी वस्तु का उपयोग करते हैं, और उस वस्तु के लिए कोई अन्य संदर्भ नहीं हैं - यह स्वचालित रूप से मेमोरी (और नक्शे से) से हटा दिया जाएगा।
let john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // overwrite the reference
// john is removed from memory!
जावास्क्रिप्ट में हथियार किसी भी कुंजी या मूल्यों को नहीं रखता है, यह सिर्फ एक अद्वितीय आईडी का उपयोग करके मुख्य मूल्य में हेरफेर करता है करता है और एक संपत्ति को मुख्य वस्तु में परिभाषित करता है।
क्योंकि यह संपत्ति को key object
विधि से परिभाषित करता है Object.definePropert()
, कुंजी को आदिम प्रकार नहीं होना चाहिए ।
और इसलिए भी कि WeapMap में वास्तव में महत्वपूर्ण मूल्य जोड़े नहीं होते हैं, हमें कमजोर संपत्ति की लंबाई संपत्ति नहीं मिल सकती है।
और हेरफेर किए गए मान को मुख्य ऑब्जेक्ट को वापस सौंपा गया है, कचरा संग्रहकर्ता आसानी से कुंजी का उपयोग कर सकता है यदि यह बिना उपयोग में है।
कार्यान्वयन के लिए नमूना कोड।
if(typeof WeapMap != undefined){
return;
}
(function(){
var WeapMap = function(){
this.__id = '__weakmap__';
}
weakmap.set = function(key,value){
var pVal = key[this.__id];
if(pVal && pVal[0] == key){
pVal[1]=value;
}else{
Object.defineProperty(key, this.__id, {value:[key,value]});
return this;
}
}
window.WeakMap = WeakMap;
})();
कार्यान्वयन का संदर्भ
id
, लेकिन यह कुछ Math.random और Date.now (), आदि का उपयोग करके अद्वितीय होना चाहिए और इस डायनेमिक आईडी को जोड़कर, पहले बिंदु को हल किया जा सकता है। क्या आप मुझे अंतिम दो बिंदुओं के लिए कोई समाधान प्रदान कर सकते हैं।
WeakMap
कुंजियाँ वस्तुएं होनी चाहिए, न कि आदिम मूल्य।
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "ok"); // works fine (object key)
// can't use a string as the key
weakMap.set("test", "Not ok"); // Error, because "test" is not an object
क्यों????
आइए नीचे उदाहरण देखें।
let user = { name: "User" };
let map = new Map();
map.set(user, "...");
user = null; // overwrite the reference
// 'user' is stored inside the map,
// We can get it by using map.keys()
यदि हम किसी वस्तु को नियमित रूप से कुंजी के रूप में उपयोग
Map
करते हैं, तो जबकिMap
मौजूद भी वह वस्तु मौजूद रहती है। यह स्मृति को घेरता है और कचरा एकत्र नहीं हो सकता है।
WeakMap
इस पहलू में मौलिक रूप से भिन्न है। यह प्रमुख वस्तुओं के कचरा-संग्रह को नहीं रोकता है।
let user = { name: "User" };
let weakMap = new WeakMap();
weakMap.set(user, "...");
user = null; // overwrite the reference
// 'user' is removed from memory!
यदि हम इसमें किसी वस्तु का उपयोग कुंजी के रूप में करते हैं, और उस वस्तु के लिए कोई अन्य सन्दर्भ नहीं हैं - तो यह स्वतः ही (और मानचित्र से) मेमोरी से हटा दी जाएगी।
WeakMap
पुनरावृत्ति और विधियों कीज़ () , मानों () , प्रविष्टियों () का समर्थन नहीं करता है , इसलिए इससे सभी कुंजी या मान प्राप्त करने का कोई तरीका नहीं है।
WeakMap में केवल निम्न विधियाँ हैं:
यह स्पष्ट है कि यदि किसी वस्तु ने अन्य सभी संदर्भों को खो दिया है (जैसे ऊपर दिए गए कोड में 'उपयोगकर्ता'), तो यह स्वचालित रूप से कचरा एकत्र करना है। लेकिन तकनीकी तौर पर यह बिल्कुल निर्दिष्ट नहीं है जब सफाई होती है।
जावास्क्रिप्ट इंजन तय करता है कि। यह स्मृति सफाई तुरंत करने या प्रतीक्षा करने और बाद में सफाई करने का चयन कर सकता है जब अधिक विलोपन होता है। इसलिए, तकनीकी रूप से वर्तमान तत्व की गणना WeakMap
ज्ञात नहीं है। इंजन ने इसे आंशिक रूप से साफ किया है या नहीं किया है। उस कारण से, सभी कुंजियों / मानों तक पहुंचने वाले तरीकों का समर्थन नहीं किया जाता है।
नोट: - WeakMap के लिए आवेदन का मुख्य क्षेत्र एक अतिरिक्त डेटा स्टोरेज है। जैसे किसी वस्तु को कैशिंग तब तक करना जब तक वह वस्तु कचरा एकत्रित न हो जाए।