ES6 মানচিত্র এবং উইকম্যাপের মধ্যে পার্থক্য কী?


94

খুঁজছি এই এবং এই MDN পেজ-মানচিত্র এবং WeakMaps মধ্যে একমাত্র পার্থক্য মত মনে হয় WeakMaps জন্য একটি অনুপস্থিত "আকার" সম্পত্তি। তবে এটা কি সত্য? তাদের মধ্যে পার্থক্য কী?


এর প্রভাব জিসির উপর পড়ে। WeakMaps তাদের কী সংগ্রহ করতে পারেন।
জন ডিভোরাক

@ জনডভোরাক এটি সম্পর্কে এমডিএন-তে নির্দেশিত কোনও উদাহরণ নেই। AWeakMap.get (কী) এর মতো; // বলুন, 2 ... (জিসি অ্যাকশন) ... aWeakMap.get (কী); // বলুন,
অপরিশোধিত

4
আপনার উদাহরণ অসম্ভব। keyসংগ্রহ করা যায় না, কারণ এটি আপনার দ্বারা রেফারেন্স করা হয়।
জন ডিভোরাক

4
ডিজাইনের সিদ্ধান্ত হ'ল জিসি ক্রিয়াগুলি জাভাস্ক্রিপ্টে অদৃশ্য। আপনি জিসি এর কাজটি পর্যবেক্ষণ করতে পারবেন না।
জন ডিভোরাক

4
দেখুন এই সংশ্লিষ্ট উত্তর এই সমস্যাটি সম্পর্কে আরও তথ্যের জন্য।
বেনিয়ামিন গ্রুইনবাউম

উত্তর:


54

খুব একই পৃষ্ঠা থেকে বিভাগ " কেন দুর্বল মানচিত্র? " :

অভিজ্ঞ জাভাস্ক্রিপ্ট প্রোগ্রামার লক্ষ্য করবে যে এই এপিআইটি জাভাস্ক্রিপ্টে 4 টি এপিআই পদ্ধতিতে ভাগ করে নেওয়া দুটি অ্যারে (কীগুলির জন্য একটি, মানগুলির জন্য একটি) প্রয়োগ করা যেতে পারে। এই ধরনের বাস্তবায়নের দুটি প্রধান অসুবিধা হবে। প্রথমটি হ'ল একটি (এন) অনুসন্ধান (এন মানচিত্রে কীগুলির সংখ্যা হওয়া)। দ্বিতীয়টি হ'ল মেমরি ফুটো ইস্যু। ম্যানুয়ালি লিখিত মানচিত্রের সাহায্যে, কীগুলির অ্যারে মূল অবজেক্টের রেফারেন্স রাখবে এবং এগুলি আবর্জনা সংগ্রহ করা থেকে বিরত রাখবে। নেটিভ WeakMaps এ, মূল বিষয়গুলির উল্লেখগুলি "দুর্বলভাবে" ধরা হয় , যার অর্থ বস্তুর সাথে অন্য কোনও রেফারেন্স না থাকলে তারা আবর্জনা সংগ্রহ আটকাবে না।

রেফারেন্সগুলি দুর্বল হওয়ার কারণে WeakMap কীগুলি গণনাযোগ্য নয় (অর্থাত্ কীগুলির তালিকা দেওয়ার কোনও পদ্ধতি নেই)। যদি তারা হয় তবে তালিকাটি অ-নির্ধারণবাদ প্রবর্তন করে আবর্জনা সংগ্রহের অবস্থার উপর নির্ভর করবে।

[এবং সে কারণেই তাদেরও sizeসম্পত্তি নেই ]

আপনি যদি কীগুলির একটি তালিকা পেতে চান তবে আপনার এটি নিজেরাই বজায় রাখা উচিত। এছাড়াও একটি ইসমাস্ক্রিপ্ট প্রস্তাব রয়েছে যার লক্ষ্য সাধারণ সেট এবং মানচিত্র প্রবর্তন করা হবে যা দুর্বল উল্লেখগুলি ব্যবহার করবে না এবং এটি গণনীয় হবে।

- যা হবে "স্বাভাবিক" Mapগুলি । MDN পদে উল্লেখিত না, কিন্তু এর মধ্যে সাদৃশ্য প্রস্তাব , তাও ছিল আছে items, keysএবং valuesজেনারেটর পদ্ধতি ও বাস্তবায়ন Iteratorইন্টারফেস


তাই new Map().get(x)একটি প্লেইন অবজেক্টে কোনও বিশিষ্টতা পড়া হিসাবে একই লুক-আপ সময় আছে?
আলেকজান্ডার মিলস

4
@ আলেকজান্ডারমিলস আমি এই প্রশ্নের সাথে কী করতে চাই তা দেখতে পাচ্ছি না, তবে এখানে কিছু তথ্য রয়েছে । সাধারণভাবে, হ্যাঁ তারা একই রকম এবং আপনার উপযুক্ত ব্যবহার করা উচিত
বার্গি

সুতরাং আমার বোধগম্যতা হ'ল মানচিত্রটি সেই অ্যারের কারণে এর কীটি ধরে রাখতে একটি অভ্যন্তরীণ অ্যারে বজায় রাখে। আবর্জনা সংগ্রহকারী রেফারেন্সটি এড়াতে সক্ষম নন। উইকম্যাপে এর কোনও অ্যারে নেই যেখানে কীগুলি কোনও কী রেফারেন্স ছাড়াই রক্ষণাবেক্ষণ করা যায় তা আবর্জনা সংগ্রহ করা যায় না।
মোহন রাম

@ মোহনরাম এ এর WeakMapএখনও প্রবেশের একটি অ্যারে (বা অন্যান্য সংগ্রহ) রয়েছে, এটি কেবল আবর্জনা সংগ্রহকারীকে বলে যে সেগুলি দুর্বল উল্লেখ
বার্গি

তাহলে কেন উইকম্যাপ কীগুলির জন্য পুনরাবৃত্তি সমর্থিত নয়?
মোহন রাম

93

যখন তাদের কী / মানগুলির দ্বারা রেফারেন্স করা কোনও বস্তু মুছে ফেলা হয় তখন তারা উভয়ই আলাদা আচরণ করে। নীচের উদাহরণ কোডটি গ্রহণ করা যাক:

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);
})()

উপরোক্ত আইআইএফই কার্যকর করা হয় সেখানে আমরা উল্লেখ করার উপায় নেই {x: 12}এবং {y: 12}আর নেই। আবর্জনা সংগ্রহকারী এগিয়ে যায় এবং "WeakMap" থেকে কী বি পয়েন্টার মুছে ফেলে এবং {y: 12}স্মৃতি থেকেও সরিয়ে দেয় । তবে "মানচিত্র" এর ক্ষেত্রে আবর্জনা সংগ্রহকারী "মানচিত্র" থেকে একটি পয়েন্টার সরিয়ে দেয় না এবং {x: 12}স্মৃতি থেকেও সরিয়ে দেয় না ।

সংক্ষিপ্তসার: WeakMap ময়লা আবর্জনা সংগ্রহকারীকে তার কাজটি করার অনুমতি দেয় তবে মানচিত্রটি নয়।

তথ্যসূত্র: http://qnimate.com/differences-between-map-and-weakmap-in- জাভাস্ক্রিপ্ট /


13
কেন এটি স্মৃতি থেকে সরানো হয় না? কারণ আপনি এখনও এটি রেফারেন্স করতে পারেন! map.entries().next().value // [{x:12}, 1]
বার্গি

4
এটি কোনও স্ব-অনুরোধিত ফাংশন নয়। এটি তাত্ক্ষণিকভাবে অনুরোধ করা ফাংশন এক্সপ্রেশন। benalman.com/news/2010/11/…
ওলসন.দেব

তাহলে দুর্বলম্যাপ এবং অবজেক্টের মধ্যে পার্থক্য কী
মুহাম্মদ উমার

@ মুহাম্মাদউমার: অবজেক্টটিতে কেবল স্ট্রিং 'কী' থাকতে পারে, যখন WeakMapকেবল অ-আদিম কী থাকতে পারে (কোন স্ট্রিং বা সংখ্যা বা Symbolকী হিসাবে কী, কেবল অ্যারে, অবজেক্ট, অন্যান্য মানচিত্র ইত্যাদি) থাকতে পারে।
আহমেদ ফসিহ

4
@nnnnnn হ্যাঁ পার্থক্য, এটি এখনও Map কিন্তু এর মধ্যে নেইWeakMap
আলেকজান্ডার ডার্ক

76

সম্ভবত পরবর্তী ব্যাখ্যা কারওর জন্য আরও স্পষ্ট হবে।

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সাথে উইকম্যাপের কী মুছে ফেলা এটিকে wmপাশাপাশি উল্লেখ দ্বারা সরিয়ে দেয় ।

এজন্য WeakMap forEach এর মতো অগণনীয় পদ্ধতি নেই, কারণ WeakMap কীগুলির তালিকার মতো কোনও জিনিস নেই, সেগুলি কেবলমাত্র অন্য অবজেক্টের রেফারেন্স।


10
শেষ লাইনে অবশ্যই, wm.get (নাল) অপরিজ্ঞাপিত হবে।
ডনিশ

8
মোজিলা সাইট থেকে কপি করা এবং পেস্ট করার চেয়ে উত্তম উত্তর k
জোয়েল হার্নান্দেজ

4
মধ্যে forEach, (key, val)আসলে হওয়া উচিত(val, key)
মিগুয়েল মোটা

অবিশ্বাস্যরকম একটি উদাহরণ যা কোনও ধারণা দেয় না যে এতগুলি
উত্সাহ

34

আর একটি পার্থক্য (উত্স: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / উইকম্যাপ ):

WeakMaps কীগুলি কেবলমাত্র অবজেক্ট টাইপ হয়। কী হিসাবে প্রাথমিক তথ্য প্রকারের অনুমতি নেই (উদাহরণস্বরূপ একটি চিহ্ন একটি উইকম্যাপ কী হতে পারে না)।

বা কোনও স্ট্রিং, সংখ্যা বা বুলেটিয়ান WeakMapকী হিসাবে ব্যবহার করা যাবে না । একটি কীগুলির জন্য আদিম মানগুলি ব্যবহার 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

6
যদি কেউ বিস্মিত হন: এর পিছনে কারণটি আমি কল্পনা করতে পারি: আপনি আদিম ধরণের উল্লেখগুলি রাখতে বা পাস করতে পারবেন না। সুতরাং কোনও উইকম্যাপে কীটি হবে এর একমাত্র রেফারেন্স। এইভাবে আবর্জনা সংগ্রহ সম্ভব হবে না। আমি জানি না দুর্বল উল্লেখগুলি অসম্ভব কিনা বা কেবল তা বোঝা যায় না। তবে উভয় উপায়ে কীটির এমন কিছু হওয়া দরকার যা দুর্বলভাবে উল্লেখ করা যেতে পারে।
আন্দ্রে লিনার্ট

3

জাভাস্ক্রিপ্ট.ইনফো থেকে

মানচিত্র - আমরা যদি কোনও নিয়মিত মানচিত্রে কোনও বস্তুটিকে কী হিসাবে ব্যবহার করি, তবে মানচিত্রটি বিদ্যমান থাকাকালীন সেই বস্তুটিও উপস্থিত রয়েছে। এটি স্মৃতি ধারণ করে এবং আবর্জনা সংগ্রহ করা নাও হতে পারে।

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()

উইকম্যাপ - এখন, আমরা যদি কোনও বস্তুকে এর কী হিসাবে ব্যবহার করি এবং সেই বস্তুর সাথে অন্য কোনও উল্লেখ নেই - এটি স্বয়ংক্রিয়ভাবে মেমরি (এবং মানচিত্র থেকে) মুছে ফেলা হবে।

let john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // overwrite the reference

// john is removed from memory!

3

জাভাস্ক্রিপ্টে ওয়েপম্যাপটি কোনও কী বা মান ধারণ করে না, এটি কেবল কোনও অনন্য আইডি ব্যবহার করে মূল মানটিকে ম্যানিপুলেট করে এবং কী বস্তুতে একটি বৈশিষ্ট্য সংজ্ঞায়িত করে।

যেহেতু এটি key objectপদ্ধতি দ্বারা সম্পত্তিকে সংজ্ঞায়িত করে Object.definePropert(), কীটি আদিম ধরণের হওয়া উচিত নয়

এবং ওয়েপম্যাপে আসলে কী মান যুক্ত থাকে না বলে আমরা দুর্বলম্যাপের দৈর্ঘ্য সম্পত্তি পেতে পারি না।

এবং ম্যানিপুলেটেড মান কী বস্তুর কাছে ফেরত দেওয়া হয়েছে, আবর্জনা সংগ্রাহক সহজেই কীটি ব্যবহার করতে না পারলে তা সংগ্রহ করতে পারেন।

বাস্তবায়নের জন্য নমুনা কোড।

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;
})();

বাস্তবায়নের রেফারেন্স


4
পরিষ্কারভাবে বলতে গেলে, এই প্রয়োগটি কেবল অর্ধেক কাজ করে। এটি একাধিক দুর্বল মানচিত্রে কী হিসাবে একই অবজেক্টটি ব্যবহার করতে দেয় না। এটি হিমশীতল বস্তুর জন্যও কাজ করে না। এবং অবশ্যই, এটি ম্যাপিং ফাঁস করে যে কোনও ব্যক্তির সাথে যার সাথে অবজেক্টের রেফারেন্স রয়েছে। প্রথমটি প্রতীক ব্যবহার করে স্থির করা যেতে পারে তবে দ্বিতীয়টি নয়।
Andreas রসবার্গ

id@ অ্যান্ড্রেসরোসবার্গ এই বাস্তবায়নে আমি হার্ডকোড যুক্ত করেছি , তবে ম্যাথ.আরন্ডম এবং ডেট.নো () ইত্যাদি ব্যবহার করে এটি অনন্য হওয়া উচিত এবং এই গতিশীল আইডি যুক্ত করে প্রথম পয়েন্টটি সমাধান করা যেতে পারে। আপনি দয়া করে আমাকে শেষ দুটি পয়েন্টের জন্য একটি সমাধান সরবরাহ করতে পারেন?
রবি সেবতা

প্রথম সমস্যাটি প্রতীক ব্যবহার করে আরও মার্জিতভাবে সমাধান করা হয়। দ্বিতীয়টি জেএসের মধ্যে সমাধান করা যায় না, এজন্যই ওয়েকম্যাপকে ভাষায় আদিম হতে হবে।
Andreas রসবার্গ

1

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জানা যায়নি। ইঞ্জিন সম্ভবত এটি পরিষ্কার করেছে বা না করেছে বা এটি আংশিকভাবে করেছে। যে কারণে সমস্ত কী / মানগুলিতে অ্যাক্সেস পাওয়া পদ্ধতিগুলি সমর্থিত নয়।

দ্রষ্টব্য: - উইকম্যাপের জন্য আবেদনের প্রধান ক্ষেত্রটি হ'ল একটি অতিরিক্ত ডেটা স্টোরেজ। কোনও বস্তুর ক্যাচিংয়ের মতো যতক্ষণ না সেই বস্তুটি আবর্জনা সংগ্রহ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.