javascript
ecmascript-6
ecmascript-harmony
weakmap
Dmitrii Sorin
sumber
sumber
key
tidak dapat dikumpulkan, karena dirujuk oleh Anda.Jawaban:
Dari halaman yang sama, bagian " Mengapa Peta Lemah ? " :
[Dan itulah mengapa mereka juga tidak memiliki
size
properti]- yang akan menjadi "normal"
Map
s . Tidak disebutkan di MDN, tetapi dalam proposal harmoni , mereka juga memilikiitems
,keys
danvalues
metode generator dan mengimplementasikanIterator
antarmuka .sumber
new Map().get(x)
memiliki waktu pencarian yang hampir sama dengan membaca properti dari objek biasa?WeakMap
masih memiliki larik (atau kumpulan entri lainnya), ini hanya memberi tahu pengumpul sampah bahwa itu adalah referensi yang lemah .Keduanya berperilaku berbeda saat objek yang direferensikan oleh kunci / nilainya dihapus. Mari kita ambil contoh kode di bawah ini:
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 di atas dijalankan tidak ada cara kami dapat referensi
{x: 12}
dan{y: 12}
lagi. Pengumpul sampah melanjutkan dan menghapus penunjuk b kunci dari "WeakMap" dan juga menghapus{y: 12}
dari memori. Tetapi dalam kasus "Peta", pengumpul sampah tidak menghapus penunjuk dari "Peta" dan juga tidak menghapus{x: 12}
dari memori.Ringkasan: WeakMap memungkinkan pengumpul sampah melakukan tugasnya tetapi tidak dengan Map.
Referensi: http://qnimate.com/difference-between-map-and-weakmap-in-javascript/
sumber
map.entries().next().value // [{x:12}, 1]
WeakMap
hanya dapat memiliki kunci non-primitif (tidak ada string atau angka atauSymbol
s sebagai kunci, hanya array, objek, peta lain, dll.).Map
tapi tidak diWeakMap
Mungkin penjelasan selanjutnya akan lebih jelas bagi seseorang.
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
Seperti yang Anda lihat, setelah menghapus
k1
kunci dari memori kita masih bisa mengaksesnya di dalam peta. Pada saat yang sama menghapusk2
kunci WeakMap akan menghapusnya dariwm
referensi.Itulah mengapa WeakMap tidak memiliki metode enumerable seperti forEach, karena tidak ada yang namanya daftar kunci WeakMap, mereka hanya referensi ke objek lain.
sumber
forEach
,(key, val)
seharusnya benar-benar(val, key)
Perbedaan lain (sumber: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ):
String, angka, atau boolean juga tidak dapat digunakan sebagai
WeakMap
kunci. AMap
dapat menggunakan nilai primitif untuk kunci.w = new WeakMap; w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key m = new Map m.set('a', 'b'); // Works
sumber
Dari Javascript.info
Peta - Jika kita menggunakan objek sebagai kunci dalam Peta biasa, maka saat Peta ada, objek itu juga ada. Ini menempati memori dan mungkin tidak dikumpulkan sampah.
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]
Mirip dengan itu, jika kita menggunakan objek sebagai kunci dalam Map biasa, maka selama Map ada, objek itu juga ada. Ini menempati memori dan mungkin tidak dikumpulkan sampah
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 - Sekarang, jika kita menggunakan objek sebagai kunci di dalamnya, dan tidak ada referensi lain ke objek itu - itu akan dihapus dari memori (dan dari peta) secara otomatis.
let john = { name: "John" }; let weakMap = new WeakMap(); weakMap.set(john, "..."); john = null; // overwrite the reference // john is removed from memory!
sumber
WeapMap di javascript tidak menyimpan kunci atau nilai apa pun, hanya memanipulasi nilai kunci menggunakan id unik dan menentukan properti ke objek kunci.
karena ia mendefinisikan properti menjadi
key object
menurut metodeObject.definePropert()
, kunci tidak boleh berjenis primitif .dan juga karena WeapMap sebenarnya tidak berisi pasangan nilai kunci, kita tidak bisa mendapatkan properti length dari weakmap.
dan juga nilai yang dimanipulasi diberikan kembali ke objek kunci, pengumpul sampah dengan mudah dapat mengumpulkan kunci jika tidak digunakan.
Kode contoh untuk implementasi.
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; })();
referensi implementasi
sumber
id
, tetapi ini harus unik dengan menggunakan sesuatu Math.random dan Date.now (), dll. Dan dengan menambahkan id dinamis ini, poin pertama dapat diselesaikan. Bisakah Anda memberi saya solusi untuk dua poin terakhir.WeakMap
kunci harus berupa objek, bukan nilai primitif.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
Mengapa????
Mari kita lihat contoh di bawah ini.
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()
let user = { name: "User" }; let weakMap = new WeakMap(); weakMap.set(user, "..."); user = null; // overwrite the reference // 'user' is removed from memory!
WeakMap
tidak mendukung iterasi dan metode kunci () , nilai () , entri () , jadi tidak ada cara untuk mendapatkan semua kunci atau nilai darinya.WeakMap hanya memiliki metode berikut:
Jelas seolah-olah sebuah objek telah kehilangan semua referensi lainnya (seperti 'pengguna' dalam kode di atas), maka objek tersebut akan dikumpulkan secara otomatis. Namun secara teknis itu tidak ditentukan secara pasti kapan pembersihan terjadi.
Mesin JavaScript memutuskan itu. Ini mungkin memilih untuk melakukan pembersihan memori segera atau menunggu dan melakukan pembersihan nanti ketika lebih banyak penghapusan terjadi. Jadi, secara teknis jumlah elemen saat ini dari a
WeakMap
tidak diketahui. Mesin mungkin telah membersihkannya atau tidak atau melakukannya sebagian. Oleh karena itu, metode yang mengakses semua kunci / nilai tidak didukung.sumber