Ù٠ا عرÙÙØ§ Ù Ù ÙØµÙ «ÙÙØ³ اÙÙ ÙÙ ÙØ§ØªÂ»Ø ÙÙ ÙØØ±ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ®ÙزÙ٠اÙÙÙÙ Ø© ÙÙ Ø§ÙØ°Ø§Ùرة طاÙ٠ا ÙÙ ÙÙ Ø£Ù ÙØµÙ ÙÙØ§ Ø´ÙØ¡ (Ø£Ù ÙÙ Ù٠استع٠اÙÙØ§ ÙØ§ØÙÙØ§). ÙÙØ°Ø§:
let john = { name: "John" };
// â«ÙÙ
ÙÙÙØ§ اÙÙØµÙ٠إÙ٠اÙÙØ§Ø¦ÙØ ÙÙ john ÙÙ Ø§ÙØ¥Ø´Ø§Ø±Ø© Ø¥ÙÙÙ
// عÙÙØ¶ تÙÙ Ø§ÙØ¥Ùشارة
john = null;
// سÙÙØ²Ø§Ù اÙÙØ§Ø¦Ù Ù
Ù Ø§ÙØ°Ø§Ùرة
عادة٠٠ا تÙÙÙ Ø®Ø§ØµÙØ§Øª اÙÙØ§Ø¦Ù Ø£Ù Ø¹ÙØ§ØµØ± اÙ٠صÙÙÙØ© Ø£Ù Ø£ÙØ© بÙÙØ© Ø¨ÙØ§Ùات Ø£Ø®Ø±Ù â Ø¹Ø§Ø¯Ø©Ù ٠ا ØªÙØ¹Ø¯Ù âÙ ÙØªØ§ØØ© ÙØ¨Ø§ÙÙ Ø§ÙØ´ÙÙØ±Ø©â ÙÙÙØ¨ÙÙÙØ§ اÙÙ ØØ±ÙÙ ÙÙ Ø§ÙØ°Ø§Ùرة طاÙ٠ا بÙÙØ© Ø§ÙØ¨ÙØ§ÙØ§Øª ÙÙØ³Ùا ÙÙ Ø§ÙØ°Ø§Ùرة.
ÙÙÙØªØ±Ø¶ Ø£ÙÙØ§ ÙØ¶Ø¹Ùا ÙØ§Ø¦ÙÙØ§ Ù٠٠صÙÙÙØ©Ø طاÙ٠ا اÙ٠صÙÙÙØ© Ù ÙØ¬Ùدة ÙÙ ÙØ´Ø§Ø± Ø¥ÙÙÙØ§Ø ÙØ³ÙÙÙ٠اÙÙØ§Ø¦Ù Ù ÙØ¬ÙØ¯ÙØ§ ÙÙ Ø§ÙØ¢Ø®Ø± ØØªÙÙ ÙÙ ÙÙ ÙÙÙ ÙÙØ§Ù ٠ا ÙÙØ´Ùر Ø¥ÙÙÙ. Ù Ø«Ù٠ا ÙÙ ÙØ°Ù Ø§ÙØ´ÙÙØ±Ø©:
let john = { name: "John" };
let array = [ john ];
john = null; // عÙÙØ¶ Ø§ÙØ¥Ø´Ø§Ø±Ø©
// the object previously referenced by john is stored inside the array
// therefore it won't be garbage-collected
// we can get it as array[0]
ÙØ¨ÙÙØ³ اÙÙ
ÙÙÙÙ
Ø Ù٠استعÙ
ÙÙØ§ ÙØ§Ø¦ÙÙØ§ ÙÙÙÙÙ Ù
ÙØªØ§ØÙا Ù٠خارطة Map Ø¹Ø§Ø¯ÙØ©Ø ÙØ³ÙبÙÙ ÙØ°Ø§ اÙÙØ§Ø¦Ù Ù
ÙØ¬Ø¯Ùا طاÙÙ
ا Ø§ÙØ®Ø§Ø±Ø·Ø© تÙÙ Ù
ÙØ¬ÙØ¯Ø©Ø ÙÙØ´ØºÙ Ø§ÙØ°Ø§Ùرة Ù
Ø§ÙØ¹Ùا عÙ
ÙÙØ© ÙÙØ³ اÙÙ
ÙÙ
ÙØ§Øª Ù
Ù ØªØØ±ÙØ±ÙØ§. Ø¥ÙÙÙ ÙØ°Ø§ اÙÙ
ثاÙ:
let john = { name: "John" };
let map = new Map();
map.set(john, "...");
john = null; // عÙÙØ¶ Ø§ÙØ¥Ø´Ø§Ø±Ø©
// â«Ø§ÙÙØ§Ø¦Ù john Ù
خزÙ٠داخ٠خارطة
// â«ÙÙÙ
ÙÙÙØ§ Ø£Ø®Ø°Ù Ø¨ÙØ°Ù: map.keys()â
عÙÙ Ø§ÙØ¹Ùس ÙØ§Ùخارطة ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© WeakMap Ù
ختÙÙØ© جذرÙÙØ§ Ø¹Ù ÙØ°Ø§Ø ÙÙØ§ تÙ
ÙØ¹ ÙÙØ³ Ù
ÙÙ
ÙØ§Øª Ø£ÙÙÙ Ù
Ù Ù
ÙØ§ØªÙØÙا اÙÙØ§Ø¦Ùات. ÙÙØ£Ø®Ø° بعض Ø§ÙØ£Ù
Ø«ÙØ© ÙØªÙدر٠اÙÙØµØ¯ ÙÙØ§.
WeakMap
The first difference between Map and WeakMap is that keys must be objects, not primitive values:
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "ok"); // ÙØ§ Ù
شاÙÙ (اÙÙ
ÙØªØ§Ø ÙØ§Ø¦Ù)
// ÙØ§ ÙÙ
Ù٠استعÙ
Ø§Ù Ø§ÙØ³ÙØ³ÙØ© اÙÙØµÙØ© Ù
ÙØªØ§ØÙا
weakMap.set("test", "Whoops"); // â«Ø®Ø·Ø£Ø ÙØ£ÙÙ âtestâ ÙÙØ³ ÙØ§Ø¦ÙÙØ§
بعد ذÙÙ Ù٠استع٠ÙÙØ§ Ø£ØØ¯ اÙÙØ§Ø¦Ùات ÙÙÙÙÙ Ù ÙØªØ§ØÙا ÙÙÙØ§Ø ÙÙÙ ÙÙÙ ÙÙØ§Ù ٠ا ÙÙØ´Ùر Ø¥ÙÙ ÙØ°Ø§ اÙÙØ§Ø¦ÙØ ÙØ³ÙÙØ²Ø§Ù اÙÙØ§Ø¦Ù Ù Ù Ø§ÙØ°Ø§Ùرة (ÙØ§Ùخارطة) تÙÙØ§Ø¦Ùا.
let john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // عÙÙØ¶ Ø§ÙØ¥Ø´Ø§Ø±Ø©
// â«Ø£ÙزÙ٠اÙÙØ§Ø¦Ù john Ù
Ù Ø§ÙØ°Ø§Ùرة!
ÙØ§Ø²ÙÙ ÙØ°Ù Ø§ÙØ´ÙÙØ±Ø© بشÙÙØ±Ø© Ø§ÙØ®Ø§Ø±Ø·Ø© Map Ø£Ø¹ÙØ§Ù. Ø§ÙØ¢Ù ØØªÙ ÙÙ ÙÙ
ÙÙÙ john Ù
ÙØ¬ÙØ¯ÙØ§ Ø¥ÙØ§ Ù
ÙØªØ§ØÙا ÙÙÙ WeakMapØ ÙØ³ÙÙØØ°Ù ØªÙÙØ§Ø¦ÙÙØ§ Ù
Ù Ø§ÙØ®Ø§Ø±Ø·Ø© (ÙÙ
Ù Ø§ÙØ°Ø§Ùرة).
ÙØ§ تدعÙ
Ø§ÙØ®Ø§Ø±Ø·Ø© ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© WeakMap Ø§ÙØªÙرار (iteration) ÙÙØ§ Ø§ÙØªÙØ§Ø¨ÙØ¹ keys()â Ø£Ù values()â Ø£Ù entries()âØ ÙÙÙØ°Ø§ ÙØ§ ÙÙØ¯Ø± عÙ٠أخذ ÙÙ٠اÙÙ
ÙØ§ØªÙØ Ø£Ù Ø§ÙÙÙÙ
Ø§ÙØªÙ ÙÙÙØ§. ب٠أÙÙ ÙÙØ®Ø§Ø±Ø·Ø© WeakMap Ø§ÙØªÙØ§Ø¨ÙØ¹ Ø§ÙØ¢ØªÙØ©:
weakMap.get(key)âweakMap.set(key, value)âweakMap.delete(key)âweakMap.has(key)â
The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically, the current element count of a WeakMap is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access all keys/values are not supported.
Now, where do we need such a data structure?
Ø§Ø³ØªØ¹Ù Ø§ÙØ§ØªÙا: Ø¨ÙØ§Ùات إضاÙÙØ©
اÙÙ
Ø¬Ø§Ù Ø§ÙØ±Ø¦ÙØ³Ù ÙØªØ·Ø¨ÙÙØ§Øª WeakMap Ù٠تخزÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª Ø§ÙØ¥Ø¶Ø§ÙÙØ©.
ÙÙ ÙÙÙØ§ ÙØªØ¹Ø§Ù
Ù Ù
ع ÙØ§Ø¦Ù âÙÙØªÙ
Ùâ Ø¥ÙÙ Ø´ÙÙØ±Ø© أخر٠(ÙØØªÙÙ Ù
ÙØªØ¨Ø© Ù
Ù Ø·Ø±Ù Ø«Ø§ÙØ«) ÙØ£Ø±Ø¯Ùا تخزÙÙ Ø¨ÙØ§Ùات Ù
عÙÙÙØ© ÙØªØ±ØªØ¨Ø· Ø¨ÙØ§Ø ÙÙØ°Ù Ø§ÙØ¨ÙØ§ÙØ§Øª ÙØ§ تÙÙÙ Ù
ÙØ¬Ùدة Ø¥ÙØ§ ÙÙ ÙØ§Ù اÙÙØ§Ø¦Ù Ù
ÙØ¬ÙØ¯ÙØ§Ø ÙÙÙ WeakMap ÙÙ Ù
ا ÙØ±Ùد تÙ
اÙ
ÙØ§: ÙØ¶Ø¹ Ø§ÙØ¨ÙØ§ÙØ§Øª Ù٠خارطة بإشارة ضعÙÙØ© WeakMap (Ù
ستعÙ
ÙÙ٠اÙÙØ§Ø¦Ù Ù
ÙØªØ§ØÙا ÙÙØ§). Ù
ت٠Ù
ا ÙÙÙØ³ اÙÙØ§Ø¦Ù باعتبار٠Ù
ÙÙ
ÙØ§ØªØ ستختÙ٠تÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª Ù
Ø¹Ù Ø£ÙØ¶Ùا.
weakMap.set(john, "secret documents");
// â«Ø¥Ù Ù
ات john ÙØ³ØªÙدÙ
ÙØ± تÙ٠اÙÙ
Ø³ØªÙØ¯Ø§Øª ÙØ§Ø¦ÙØ© Ø§ÙØ³Ø±ÙØ© تÙÙØ§Ø¦ÙÙØ§
ÙÙØ±Ù ٠ثاÙÙØ§ ÙÙØ¶ÙØ Ø§ÙØµÙرة. Ø¹ÙØ¯Ù بأÙÙ ÙØ¯ÙÙØ§ Ø´ÙÙØ±Ø© تسجÙ٠عدد Ø²ÙØ§Ø±Ø§Øª اÙ٠ستخد٠ÙÙ â ØªØ³Ø¬ÙÙÙØ§ ÙÙ Ø®Ø§Ø±Ø·Ø©Ø ØÙØ« ÙØ§Ø¦Ù اÙ٠ستخد٠ÙÙ Ù ÙØªØ§ØÙا ÙØ¹Ø¯Ø¯ Ø²ÙØ§Ø±Ø§ØªÙ Ù٠اÙÙÙÙ Ø©. ÙØ§ ÙØ±Ùد Ø£Ù ÙÙØ³Ø¬Ù٠عدد Ø²ÙØ§Ø±Ø§ØªÙ ÙÙ٠ا Ù٠غادر اÙ٠ستخد٠(أ٠أÙ٠ع٠ÙÙØ© ÙÙØ³ اÙÙ ÙÙ ÙØ§Øª ÙÙØ³Øª ذا٠اÙÙØ§Ø¦Ù).
Ø¥ÙÙÙ Ù
ثاÙÙØ§ آخر Ø¹Ù Ø¯Ø§ÙØ© Ø¹ÙØ¯Ù باستعÙ
ا٠Map:
// ð visitsCount.js
let visitsCountMap = new Map(); // خارطة: اÙÙ
ستخدÙ
=> عدد Ø²ÙØ§Ø±Ø§ØªÙ
// ØªØ²ÙØ¯ عدد Ø§ÙØ²Ùارات
function countUser(user) {
let count = visitsCountMap.get(user) || 0;
visitsCountMap.set(user, count + 1);
}
ÙÙØ°Ø§ Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ«Ø§ÙÙ Ù Ù Ø§ÙØ´ÙÙØ±Ø© (ÙÙ ÙÙ Ø£Ù ÙØ³ØªØ¹Ù Ù ÙØ°Ø§ اÙÙ Ù٠ذاÙ):
// ð main.js
let john = { name: "John" };
countUser(john); // Ø¹ÙØ¯Ù Ø§ÙØ²ÙÙØ§Ø±
countUser(john);
// â«Ø¨Ø¹Ø¯Ùا ÙØºØ§Ø¯Ø± john Ø§ÙØÙÙØ©
john = null;
Now, john object should be garbage collected, but remains in memory, as itâs a key in visitsCountMap.
عÙÙÙØ§ Ù
Ø³Ø visitsCountMap ØÙÙ ÙÙØ²Ù٠اÙÙ
ستخدÙ
ÙÙ ÙØ¥Ùا ÙØ³ÙØ²ÙØ¯ ØØ¬Ù
ÙØ§ ÙÙ Ø§ÙØ°Ø§Ùرة Ø¥Ù٠آباد Ø§ÙØ¢Ø¨Ø¯ÙÙ. ÙÙ ÙØ§Ùت بÙÙØ© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ù
عÙÙØ¯Ø©Ø ÙØ³ØªÙÙ٠عÙ
ÙÙØ© اÙÙ
Ø³Ø ÙØ°Ù Ù
رÙÙØ© Ø¬Ø¯ÙØ§ ÙØºÙر عÙ
ÙÙØ©. ÙÙØ°Ø§ ÙÙ
ÙÙÙØ§ تجÙÙØ¨ Ø§ÙØªØ¹Ø¨ ÙØ§Ø³ØªØ¹Ù
ا٠WeakMap Ø¨Ø¯Ù Ø§ÙØ¹Ø§Ø¯ÙØ©:
// ð visitsCount.js
let visitsCountMap = new WeakMap(); // خارطة بإشارة ضعÙÙØ©: اÙÙ
ستخدÙ
=> عدد Ø²ÙØ§Ø±Ø§ØªÙ
// ØªØ²ÙØ¯ عدد Ø§ÙØ²Ùارات
function countUser(user) {
let count = visitsCountMap.get(user) || 0;
visitsCountMap.set(user, count + 1);
}
Now we donât have to clean visitsCountMap. After john object becomes unreachable, by all means except as a key of WeakMap, it gets removed from memory, along with the information by that key from WeakMap.
Ø§Ø³ØªØ¹Ù Ø§ÙØ§ØªÙا: Ø§ÙØ®Ø¨Ùئة
Another common example is caching. We can store (âcacheâ) results from a function, so that future calls on the same object can reuse it.
To achieve that, we can use Map (not optimal scenario):
// ð cache.js
let cache = new Map();
// ÙØØ³Ø¨ اÙÙØªÙجة ÙÙØªØ°ÙØ±ÙØ§
function process(obj) {
if (!cache.has(obj)) {
let result = /* ØØ³Ø§Ø¨Ø§Øª اÙÙØ§Ø¦Ù ÙØ°Ø§ */ obj;
cache.set(obj, result);
}
return cache.get(obj);
}
// Ø§ÙØ¢Ù ÙØ³ØªØ¹Ù
Ù â«process()â ÙÙ Ù
Ù٠آخر:
// ð main.js
let obj = {/* ÙÙÙÙØªØ±Ø¶ ÙØ¬Ùد ÙØ°Ø§ اÙÙØ§Ø¦Ù*/};
let result1 = process(obj); // ØØ³Ø¨Ùا اÙÙÙÙ
Ø©
// â«...Ø¨Ø¹Ø¯ÙØ§Ø ÙÙ Ù
ÙØ§Ù آخر Ù
Ù Ø§ÙØ´ÙÙØ±Ø©...
let result2 = process(obj); // ØªÙØ£Ø®Ø° اÙÙØªÙجة تÙÙ Ù
Ù Ø§ÙØ®Ø¨Ùئة
// â«...Ø¨Ø¹Ø¯ÙØ§Ø ÙÙ ÙÙ
ÙØ±Ø¯ اÙÙØ§Ø¦Ù بعد Ø§ÙØ¢Ù:
obj = null;
alert(cache.size); // 1 (ÙØ§Ø§! Ù
ا زا٠اÙÙØ§Ø¦Ù ÙÙ Ø§ÙØ®Ø¨Ùئة ÙÙØ³ØªÙÙÙ Ø§ÙØ°Ø§Ùرة)
Ù٠استدعÙÙØ§ process(obj)â Ø£Ùثر Ù
Ù Ù
Ø±ÙØ© بتÙ
Ø±ÙØ± ÙÙØ³ اÙÙØ§Ø¦ÙØ ÙØ³ØªØØ³Ø¨ Ø§ÙØ´ÙÙØ±Ø© اÙÙØªÙجة Ø£ÙÙÙ Ù
رة ÙÙØ·Ø ÙÙ٠اÙÙ
رات اÙÙØ§Ø¯Ù
Ø© ØªØ£Ø®Ø°ÙØ§ Ù
٠اÙÙØ§Ø¦Ù cache. Ù
Ø´ÙÙØ© ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ© ÙÙ Ø¶Ø±ÙØ±Ø© Ù
Ø³Ø cache Ù
ت٠Ù
ا Ø§ÙØªÙت ØØ§Ø¬ØªÙا Ù
٠اÙÙØ§Ø¦Ù.
If we replace Map with WeakMap, then this problem disappears. The cached result will be removed from memory automatically after the object gets garbage collected.
// ð cache.js
let cache = new WeakMap();
// ÙØØ³Ø¨ اÙÙØªÙجة ÙÙØªØ°ÙØ±ÙØ§
function process(obj) {
if (!cache.has(obj)) {
let result = /* ØØ³Ø§Ø¨Ø§Øª اÙÙØ§Ø¦Ù ÙØ°Ø§ */ obj;
cache.set(obj, result);
}
return cache.get(obj);
}
// ð main.js
let obj = {/* ÙØ§Ø¦Ù Ù
٠اÙÙØ§Ø¦Ùات */};
let result1 = process(obj);
let result2 = process(obj);
// â«...Ø¨Ø¹Ø¯ÙØ§Ø ÙÙ ÙÙ
ÙØ±Ø¯ اÙÙØ§Ø¦Ù بعد Ø§ÙØ¢Ù:
obj = null;
ÙÙØ§Ø â«Ùا ÙÙ ÙÙ Ø£Ù ÙØ¹Ø±Ù cache.size إذ Ø£ÙÙØ§ خارطة بإشارة ضعÙÙØ©Ø ÙÙÙÙ Ø§ÙØØ¬Ù ØµÙØ±Ø أ٠سÙÙÙÙ ØµÙØ± ÙØ±ÙØ¨ÙØ§Ø Ù٠ا أ٠تبدأ ع٠ÙÙØ© ÙÙØ³ اÙÙ ÙÙ ÙØ§Øª عÙ٠اÙÙØ§Ø¦ÙØ Ø³ØªÙØ²Ø§Ù Ø§ÙØ¨ÙØ§ÙØ§Øª اÙÙ ÙØ®Ø¨Ùأة ÙÙ Ø§ÙØ£Ø®Ø±Ù.
WeakSet
ØØªÙÙ Ø§ÙØ£Ø·ÙÙ
ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© WeakSet تسÙ٠ذات Ø§ÙØ³ÙÙÙ:
- ØªØ´Ø¨Ù Ø§ÙØ£Ø·ÙÙ
Ø§ÙØ¹Ø§Ø¯ÙØ©
SetÙÙÙÙ ÙØ§ ÙÙ ÙÙÙØ§ Ø¥ÙÙØ§ Ø¥Ø¶Ø§ÙØ© اÙÙØ§Ø¦Ùات Ø¥ÙÙWeakSet(ÙÙÙØ³ Ø§ÙØ£ÙÙØ§Ø¹ Ø§ÙØ£ÙÙÙØ©). - ÙØ¨Ù٠اÙÙØ§Ø¦Ù Ù ÙØ¬ÙØ¯ÙØ§ ÙÙ Ø§ÙØ·Ù٠طاÙ٠ا ÙÙØ§Ù ٠ا ÙØµÙ Ø¥ÙÙÙ.
- ÙÙØ¯Ø¹Ù
-ÙÙ
ا تدعÙ
Set- Ø§ÙØªÙØ§Ø¨ÙØ¹addÙhasÙdeleteØ ÙÙÙÙ ÙØ§ تدعÙsizeØ£Ùkeys()âØ£Ù Ø§ÙØªØ¹Ø¯Ø§Ø¯.
Being âweakâ, it also serves as additional storage. But not for arbitrary data, rather for âyes/noâ facts. A membership in WeakSet may mean something about the object.
ÙÙ
ÙÙÙØ§ Ù
Ø«ÙÙØ§ Ø¥Ø¶Ø§ÙØ© اÙÙ
ستخدÙ
Ù٠إÙÙ Ø·ÙÙ
بإشارة ضعÙÙØ© WeakSet ÙÙØ³Ø¬ÙÙ Ù
٠زار Ù
ÙÙØ¹Ùا:
let visitedSet = new WeakSet();
let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
visitedSet.add(john); // Ø²Ø§Ø±ÙØ§ â«John
visitedSet.add(pete); // ÙØ¨Ø¹Ø¯Ù â«Pete
visitedSet.add(john); // ÙØ¹Ø§Ø¯ â«John
// Øªâ«ØØªÙÙ visitedSet Ø§ÙØ¢Ù عÙÙ Ù
ستخدÙ
Ù٠اثÙÙÙ
// Ùâ«Ù Ø²Ø§Ø±ÙØ§ JohnØ
alert(visitedSet.has(john)); // true
// â«ÙÙ Ø²Ø§Ø±ØªÙØ§ MaryØ
alert(visitedSet.has(mary)); // false
john = null;
// ستÙÙØ¸ÙÙ â«visitedSet تÙÙØ§Ø¦ÙÙØ§
The most notable limitation of WeakMap and WeakSet is the absence of iterations, and the inability to get all current content. That may appear inconvenient, but does not prevent WeakMap/WeakSet from doing their main job â be an âadditionalâ storage of data for objects which are stored/managed at another place.
Ø§ÙØ·Ù٠ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© ÙÙ ØªØ¬Ù ÙØ¹Ø© ØªØ´Ø¨Ù Ø§ÙØ£Ø·ÙÙ Ø§ÙØ¹Ø§Ø¯ÙØ©Ø ÙÙØ§ تخزÙÙ Ø¥ÙØ§ اÙÙØ§Ø¦Ùات ÙÙÙØ§Ø Ù٠ا ÙØªÙزÙÙÙØ§ ٠ا Ø¥Ù ØªÙØ¹Ø¯Ù Ø§ÙØ¥Ø´Ø§Ø±Ø© Ø¥ÙÙÙØ§.
ÙÙÙØ§ اÙÙÙØ¹Ø§Ù ÙØ§ ÙØ¯Ø¹Ù Ø§Ù Ø§ÙØªÙØ§Ø¨ÙØ¹ ÙØ§ÙØ®Ø§ØµÙØ§Øª Ø§ÙØªÙ ØªÙØ´Ùر Ø¥ÙÙ Ù٠اÙÙ ÙØ§ØªÙØ ÙÙÙÙ Ø§Ø Ø£Ù ØØªÙ Ø¹Ø¯Ø¯ÙØ§. اÙÙ Ø³Ù ÙØ ÙÙØ· ÙÙ Ø§ÙØ¹Ù ÙÙØ§Øª عÙÙ Ø§ÙØ¹Ùاصر ÙÙÙØ§ Ø¹ÙØµØ±Ùا Ø¨Ø¹ÙØµØ±.
ÙÙØ³ØªØ¹Ù
Ù ÙØ°Ø§Ù اÙÙÙØ¹Ø§Ù WeakMap ÙWeakSet عÙ٠أÙÙÙÙ
ا بÙÙ Ø¨ÙØ§Ùات âØ«Ø§ÙÙÙØ©â Ø¥ÙÙ Ø¬Ø§ÙØ¨ تÙÙ âØ§ÙØ£Ø³Ø§Ø³ÙØ©â ÙØªØ®Ø²ÙÙ Ø§ÙØ¹Ùاصر. ÙÙ Ø£ÙØ²Ù٠اÙÙØ§Ø¦Ù Ù
Ù Ø§ÙØªØ®Ø²ÙÙ Ø§ÙØ£Ø³Ø§Ø³ÙØ ÙÙÙ
ÙÙØ¬Ø¯ Ù٠أ٠إشارة Ø¥ÙØ§ Ù
ÙØªØ§ØÙا ÙÙ WeakMap Ø£Ù Ø¹ÙØµØ±Ùا ÙÙ WeakSetØ Ù
سØÙ٠اÙÙ
ØØ±Ù٠تÙÙØ§Ø¦ÙÙØ§.
ت٠ارÙÙ
تخزÙÙ Ø±Ø§ÙØ§Øª âØºÙØ± Ù ÙØ±Ùءةâ
Ø§ÙØ£ÙÙ ÙØ©: 5
ÙØ¯Ù٠٠صÙÙÙØ© Ù Ù Ø§ÙØ±Ø³Ø§Ø¦Ù:
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
];
ÙÙÙ ÙÙ ÙÙØ´ÙÙØ±Ø© Ø¹ÙØ¯Ù اÙÙØµÙ٠إÙÙÙØ§Ø Ø¥ÙÙØ§ Ø£ÙÙ Ø´ÙÙØ±Ø© Ø£ØØ¯ÙÙ ØªÙØ¯Ùر تÙÙ Ø§ÙØ±Ø³Ø§Ø¦ÙØ ÙØªÙضÙÙ Ø±Ø³Ø§Ø¦Ù Ø¬Ø¯ÙØ¯Ø© ÙØªÙزÙÙ ÙØ¯ÙÙ Ø©Ø ÙÙØ§ ØªØ¹Ø±Ù Ù ØªÙ ÙØØ¯Ø« ÙØ°Ø§ Ø¨Ø§ÙØ¶Ø¨Ø·.
Ø§ÙØ³Ø¤Ø§Ù ÙÙ: Ø£Ù٠بÙÙØ© ٠٠بÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª ØªØ³ØªØ¹Ù Ù ÙØªØ®Ø²ÙÙ ÙØ°Ù اÙ٠عÙÙÙ Ø© ÙÙÙÙ Ø±Ø³Ø§ÙØ©: âÙÙ ÙÙØ±Ø£ØªØâ. ÙØ¬Ø¨ أ٠تÙÙÙ Ø§ÙØ¨ÙÙØ© Ø§ÙØªÙ Ø§Ø®ØªØ±ØªÙØ§ Ù ÙØ§Ø³Ø¨Ø© ÙØªØ±Ø¯Ù عÙ٠سؤا٠âÙÙ ÙÙØ±Ø£ØªØâ ÙÙÙÙ ÙØ§Ø¦Ù Ø±Ø³Ø§ÙØ©.
Ù
ÙØ§ØØ¸Ø©: ØÙÙ ØªÙØ²Ø§Ù Ø±Ø³Ø§ÙØ© Ù
Ù Ù
صÙÙÙØ© messagesØ ÙØ¬Ø¨ أ٠تختÙÙ Ù
٠بÙÙØ© Ø§ÙØ¨ÙØ§ÙØ§Øª ÙØ¯ÙÙ ÙÙ Ø§ÙØ£Ø®Ø±Ù.
Ù ÙØ§ØØ¸Ø© أخرÙ: ÙØ¬Ø¨ Ø£ÙÙØ§ ÙÙØ¹Ø¯ÙÙ ÙØ§Ø¦Ùات Ø§ÙØ±Ø³Ø§Ø¦Ù ÙÙØ§ ÙÙØ¶ÙÙ Ø®Ø§ØµÙØ§Øª Ù Ù Ø¹ÙØ¯Ùا Ø¥ÙÙÙØ§Ø ÙÙÙ ÙÙ Ø£Ù ÙØ¤Ø¯ÙÙ ÙØ°Ø§ Ø¥ÙÙ Ø¹ÙØ§Ùب ÙØ®ÙÙ Ø© إذ ÙØ³Ùا Ù Ù ÙØ¯ÙØ±ÙØ§ Ø¨Ù Ø£ØØ¯ آخر.
Ø§ÙØÙ
ÙÙØ¬Ø±Ùب تخزÙÙ Ø§ÙØ±Ø³Ø§Ø¦Ù اÙÙ
ÙØ±Ùءة ÙÙ Ø·ÙÙ
بإشارة ضعÙÙØ© WeakSet:
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
];
let readMessages = new WeakSet();
// ÙØ±Ø£ اÙÙ
ستخدÙ
Ø±Ø³Ø§ÙØªÙÙ Ø§Ø«ÙØªÙÙ
readMessages.add(messages[0]);
readMessages.add(messages[1]);
// ÙÙ â«readMessages Ø§ÙØ¢Ù Ø¹ÙØµØ±ÙÙ
// â«...ÙÙÙØ§ ÙÙØ¹Ùد ÙØ±Ø§Ø¡Ø© Ø£ÙÙ Ø±Ø³Ø§ÙØ©!
readMessages.add(messages[0]);
// Ù
ا Ø²Ø§ÙØª ÙÙ â«readMessages Ø¹ÙØµØ±ÙÙ ÙØ±ÙدÙÙ
// â«Ø§ÙØ¬ÙØ§Ø¨: ÙÙ ÙÙØ±Ø¦Øªmessage [0]âØ
alert("Read message 0: " + readMessages.has(messages[0])); // ÙØ¹Ù
â«true
messages.shift();
// Ø§ÙØ¢Ù ÙÙ â«readMessages Ø¹ÙØµØ± ÙØ§ØØ¯ (تÙÙÙÙØ§ ÙØ³ØªÙÙØ¸ÙÙ Ø§ÙØ°Ø§Ùرة ÙÙÙ
ا بعد)
ÙØªÙØ ÙÙØ§ Ø§ÙØ·ÙÙ
ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© تخزÙÙÙ Ù
جÙ
ÙØ¹Ø© Ù
Ù Ø§ÙØ±Ø³Ø§Ø¦Ù ÙØ§ÙتأÙÙØ¯ Ù
Ù ÙØ¬Ùد ÙÙÙ Ù
ÙÙØ§ بسÙÙÙØ© تاÙ
Ø©. ÙÙ
ا ÙØ£ÙÙÙØ§ تÙ
Ø³Ø ÙÙØ³Ùا بÙÙØ³Ùا. ÙÙØ£Ø³Ù Ø¨ÙØ°Ø§ ÙÙØ¶ØÙ٠بÙ
ÙØ²Ø© Ø§ÙØªÙØ±Ø§Ø±Ø ÙÙØ§ ÙÙ
ÙÙ Ø£Ù ÙØ¬Ùب âÙÙÙ Ø§ÙØ±Ø³Ø§Ø¦Ù اÙÙ
ÙØ±Ùءةâ Ù
ÙÙØ§ Ù
Ø¨Ø§Ø´Ø±Ø©ÙØ ÙÙÙÙ⦠ÙÙ
ÙÙÙØ§ اÙÙ
Ø±ÙØ± عÙÙ Ø¹ÙØ§ØµØ± ÙÙ Ø§ÙØ±Ø³Ø§Ø¦Ù ÙÙ messages ÙØªØ±Ø´ÙØ ØªÙÙ Ø§ÙØªÙ ÙÙ Ø§ÙØ·ÙÙ
ÙØ¯ÙÙØ§.
ÙÙ
Ù٠أ٠ÙÙÙÙ Ø§ÙØÙ Ø§ÙØ¢Ø®Ø± ÙÙ Ø¥Ø¶Ø§ÙØ© Ø®Ø§ØµÙØ© Ù
ث٠message.isRead=true Ø¥ÙÙ Ø§ÙØ±Ø³Ø§ÙØ© بعد ÙØ±Ø§Ø¡ØªÙا. ÙÙÙÙÙÙØ§ ÙØ³Ùا Ù
Ù ÙÙØ¯Ùر ÙØ°Ù اÙÙØ§Ø¦Ùات Ø¨Ù Ø£ØØ¯ Ø¢Ø®Ø±Ø ÙÙÙØ°Ø§ ÙØ§ ÙÙÙØµÙ بذÙÙ Ø¨ØµÙØ© عاÙ
Ø©. ÙÙÙÙØ ÙÙ
ÙÙÙØ§ استعÙ
ا٠خاصÙÙØ© رÙ
Ø²ÙØ© ÙÙØªØ¬ÙÙØ¨ Ø£Ù Ù
Ø´ÙÙØ© أ٠تعارض.
ÙÙØ°Ø§:
// Ø§ÙØ®Ø§ØµÙØ© Ø§ÙØ±Ù
Ø²ÙØ© Ù
عرÙÙØ© ÙÙ Ø§ÙØ´ÙÙØ±Ø© ÙØ¯ÙÙØ§Ø ÙÙØ·
let isRead = Symbol("isRead");
messages[0][isRead] = true;
âÙØ±Ø¨Ù Ø§â Ø§ÙØ¢Ù Ù٠تعر٠شÙÙØ±Ø© Ø§ÙØ·Ø±Ù Ø§ÙØ«Ø§ÙØ« Ø¨Ø®Ø§ØµÙØªÙا Ø§ÙØ¬Ø¯Ùدة.
صØÙØ Ø£Ù Ø§ÙØ±Ù
ÙØ² ØªØªÙØ ÙÙØ§ تÙÙÙÙ Ø§ØØªÙ
Ø§Ù ØØ¯ÙØ« اÙÙ
شاÙÙØ Ø¥ÙÙØ§ Ø£Ù٠استعÙ
ا٠WeakSet Ø£ÙØ¶Ù بعÙ٠بÙÙØ© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ©.
تخزÙÙ ØªÙØ§Ø±ÙØ® اÙÙØ±Ø§Ø¡Ø©
Ø§ÙØ£ÙÙ ÙØ©: 5
ÙØ¯Ù٠٠صÙÙÙØ© Ù Ù Ø§ÙØ±Ø³Ø§Ø¦Ù تشب٠تÙÙ ÙÙ Ø§ÙØªÙ رÙÙ Ø§ÙØ³Ø§Ø¨ÙØ ÙØ§ÙÙÙØ±Ø© ÙÙØ§ Ù ØªØ´Ø§Ø¨ÙØ© ÙÙÙÙÙØ§.
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
];
Ø§ÙØ³Ø¤Ø§Ù: Ø£Ù٠بÙÙØ© Ø¨ÙØ§Ùات ØªØ³ØªØ¹Ù Ù ÙØªØ®Ø²ÙÙ ÙØ°Ù اÙ٠عÙÙÙ Ø©: " ٠ت٠ÙÙØ±Ø¦Øª ÙØ°Ù Ø§ÙØ±Ø³Ø§ÙØ©Ø".
ÙØ§Ù عÙÙÙ (ÙÙ Ø§ÙØªÙ رÙÙ Ø§ÙØ³Ø§Ø¨Ù) تخزÙ٠٠عÙÙÙ Ø© âÙØ¹Ù /ÙØ§â ÙÙØ·Ø Ø£Ù ÙØ§ Ø§ÙØ¢Ù ÙØ¹ÙÙ٠تخزÙÙ Ø§ÙØªØ§Ø±ÙØ®Ø ÙÙØ¬Ø¨ Ø£Ù ÙØ¨ÙÙ ÙÙ Ø§ÙØ°Ø§Ùرة Ø¥Ù٠أ٠تÙÙÙØ³ Ø§ÙØ±Ø³Ø§ÙØ© عÙ٠أÙÙÙØ§ Ù ÙÙ ÙØ§Øª.
Ù
ÙØ§ØØ¸Ø©: ØªÙØ®Ø²ÙÙ Ø§ÙØªÙØ§Ø±ÙØ® ÙØ§Ø¦Ùات بصÙÙ Date اÙÙ
ضÙ
ÙÙ Ù٠اÙÙØºØ©Ø ÙØ³ÙتÙÙÙ
عÙÙ ÙØ§ØÙÙØ§.
Ø§ÙØÙ
ÙÙ ÙÙ Ø£Ù ÙØ³ØªØ¹Ù Ù Ø§ÙØ®Ø§Ø±Ø·Ø© ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© ÙØªØ®Ø²ÙÙ Ø§ÙØªØ§Ø±ÙØ®:
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
];
let readMap = new WeakMap();
readMap.set(messages[0], new Date(2017, 1, 1));
// Ø³ÙØ±Ù Ø£Ù
ر ÙØ§Ø¦Ù Ø§ÙØªØ§Ø±ÙØ® ÙØ§ØÙÙØ§
Their main advantages are that they have weak reference to objects, so they can easily be removed by garbage collector.
That comes at the cost of not having support for clear, size, keys, valuesâ¦
WeakMap and WeakSet are used as âsecondaryâ data structures in addition to the âprimaryâ object storage. Once the object is removed from the primary storage, if it is only found as the key of WeakMap or in a WeakSet, it will be cleaned up automatically.
Ø§ÙØªØ¹ÙÙÙØ§Øª
<code>Ø ÙÙÙÙØ«Ùر Ù Ù Ø§ÙØ³Ø·Ùر استخدÙ<pre>Ø ÙÙØ£Ùثر Ù Ù 10 Ø³Ø·ÙØ± استخد٠(plnkr, JSBin, codepenâ¦)