2016-03-09 4 views
12

डॉक्स की मेरी समझ (here और here) के आधार पर यह काम करने के लिए एक स्मृति पते के लिए एक संदर्भ की आवश्यकता होगी:कैसे ES6 मानचित्र की परतें काम करते हो

const foo = {}; 
const map = new Map(); 
map.set(foo,'123'); // Can only be done if memory address of `foo` is known. Any other shimming would require stringification of foo 

इसका कारण यह है जावास्क्रिप्ट वस्तु {} कुंजी केवल तार हो सकते हैं (कम से कम ES5 में)।

फिर भी मुझे Map शिम उपलब्ध है: https://github.com/zloirock/core-js#map। मैं स्रोत पढ़ने की कोशिश की, लेकिन इसके भी बड़े करीने से निकाला (internally का उपयोग करता strong collection which then imports 10 more files)

प्रश्न

उत्तर कृपया निम्नलिखित

  • के किसी भी वहाँ यह करने के लिए एक सरल चाल है और यह सही मायने में भी किया जा सकता है (स्ट्रिंग के बिना)?
  • शायद यह foo पर कुछ स्ट्रिंग स्टोर करने के लिए mutates और फिर उस कुंजी के रूप में उपयोग करता है?
  • कुछ और शायद मैं दस्तावेज़ों को गलत पढ़ रहा हूं?
+4

मुझे पूरा यकीन है कि शिम्स ऑब्जेक्ट पहचान की तुलना करने के लिए बस '===' का उपयोग करते हैं, और ओ (1) या ओ (लॉग (एन)) संचालन के बजाय कई ओ (एन) संचालन के लिए है कि देशी कार्यान्वयन हो सकता है। –

+0

ES2015 'मानचित्र' को सही ढंग से नहीं बदला जा सकता है, मेरा मानना ​​है कि निकटतम इम्प्लांटेशन कुंजी के रिकॉर्ड, कुछ प्रकार के पुनरावृत्ति, और ऑब्जेक्ट्स के साथ नियमित तुलना करना होगा, क्योंकि जेरेमी भी उल्लेख करता है। – adeneo

+0

[यहां है] (https://cloud.github.com/downloads/eriwen/es6-map-shim/es6-map-shim-0.2।जेएस) एक पठनीय पॉलीफिल बीटीडब्ल्यू – adeneo

उत्तर

7

दो तरीके जो मन में आ रहे हैं। सबसे पहले, जाहिर है, आप चाबियों का एक सरणी हो सकता है, और यह रैखिक खोज:

Map1 = { 
 
    keys: [], 
 
    values: [], 
 
}; 
 

 
Map1.set = function(key, val) { 
 
    var k = this.keys.indexOf(key); 
 
    if(k < 0) 
 
     this.keys[k = this.keys.length] = key; 
 
    this.values[k] = val; 
 
}; 
 

 
Map1.get = function(key) { 
 
    return this.values[this.keys.indexOf(key)]; 
 
}; 
 

 

 
foo = {}; 
 
bar = {}; 
 

 
Map1.set(foo, 'xxx'); 
 
Map1.set(bar, 'yyy'); 
 

 
document.write(Map1.get(foo) + Map1.get(bar) + "<br>")

दूसरा विकल्प एक वस्तु है जो एक के रूप में प्रयोग किया जाता है के लिए एक विशेष "कुंजी" मार्कर जोड़ने के लिए है कुंजी:

Map2 = { 
 
    uid: 0, 
 
    values: {} 
 
}; 
 

 
Map2.set = function(key, val) { 
 
    key = typeof key === 'object' 
 
     ? (key.__uid = key.__uid || ++this.uid) 
 
     : String(key); 
 
    this.values[key] = val; 
 
}; 
 

 
Map2.get = function(key) { 
 
    key = typeof key === 'object' 
 
     ? key.__uid 
 
     : String(key); 
 
    return this.values[key]; 
 
}; 
 

 

 
foo = {}; 
 
bar = {}; 
 

 
Map2.set(foo, 'xxx'); 
 
Map2.set(bar, 'yyy'); 
 

 
document.write(Map2.get(foo) + Map2.get(bar) + "<br>")

1 विकल्प के विपरीत, दूसरा एक है हे (1)। इसे uid गैर-लिखने योग्य/गणना करने के द्वारा और अधिक सटीक किया जा सकता है। इसके अलावा, प्रत्येक Map का अपना "यूआईडी" नाम होना चाहिए (इसे मानचित्र कन्स्ट्रक्टर में आसानी से स्थापित किया जा सकता है)।

7

चाल पुनरावृत्ति और सख्त का उपयोग कर तुलना-बजाय एक सच्चे हैश फंक्शन जो होगा हे (1) देखने का उपयोग करके एक सरणी में स्टोर और में हे (एन) देखने प्रदर्शन करने के लिए समय है। उदाहरण के लिए इस पर विचार करें:

var myObj = {}; 

var someArray = [{}, {}, myObj, {}]; 

console.log(someArray.indexOf(myObj)); // returns 2 

यहाँ एक और जवाब से मेरी दिया गया है: Javascript HashTable use Object key

function Map() { 
    var keys = [], values = []; 

    return { 
     put: function (key, value) { 
      var index = keys.indexOf(key); 
      if(index == -1) { 
       keys.push(key); 
       values.push(value); 
      } 
      else { 
       values[index] = value; 
      } 
     }, 
     get: function (key) { 
      return values[keys.indexOf(key)]; 
     } 
    }; 
} 
संबंधित मुद्दे