ê°ë¹ì§ 컬ë ì ìì ë°°ì ë¯ì´ ìë°ì¤í¬ë¦½í¸ ìì§ì ëë¬ ê°ë¥í (ê·¸ë¦¬ê³ ì¶í ì¬ì©ë ê°ë¥ì±ì´ ìë) ê°ì ë©ëª¨ë¦¬ì ì ì§í©ëë¤.
ìì:
let john = { name: "John" };
// ì ê°ì²´ë johnì´ë¼ë 참조를 íµí´ ì ê·¼í ì ììµëë¤.
// ê·¸ë°ë° 참조를 nullë¡ ë®ì´ì°ë©´ ì ê°ì²´ì ë ì´ì ëë¬ì´ ê°ë¥íì§ ìê² ëì´
john = null;
// ê°ì²´ê° ë©ëª¨ë¦¬ìì ìì ë©ëë¤.
ìë£êµ¬ì¡°ë¥¼ 구ì±íë ììë ìì ì´ ìí ìë£êµ¬ì¡°ê° ë©ëª¨ë¦¬ì ë¨ììë ëì ëê° ëë¬ ê°ë¥í ê°ì¼ë¡ ì·¨ê¸ëì´ ë©ëª¨ë¦¬ìì ìì ëì§ ììµëë¤. ê°ì²´ì íë¡í¼í°ë ë°°ì´ì ìì, ë§µì´ë ì ì 구ì±íë ììë¤ì´ ì´ì í´ë¹í©ëë¤.
ì를 ë¤ì´ë´ ìë¤. ë°°ì´ì ê°ì²´ íë를 ì¶ê°í´ ë³´ê² ìµëë¤. ì´ë ë°°ì´ì´ ë©ëª¨ë¦¬ì ë¨ììë í, ë°°ì´ì ììì¸ ì´ ê°ì²´ë ë©ëª¨ë¦¬ì ë¨ììê² ë©ëë¤. ì´ ê°ì²´ë¥¼ 참조íë ê²ì´ ì무ê²ë ìëë¼ë ë§ì´ì£ .
ìë ì½ë를 íµí´ íì¸í´ë´ ìë¤.
let john = { name: "John" };
let array = [ john ];
john = null; // 참조를 nullë¡ ë®ì´ì
// johnì ëíë´ë ê°ì²´ë ë°°ì´ì ììì´ê¸° ë문ì ê°ë¹ì§ 컬ë í°ì ëìì´ ëì§ ììµëë¤.
// array[0]ì ì´ì©íë©´ í´ë¹ ê°ì²´ë¥¼ ì»ë ê²ë ê°ë¥í©ëë¤.
alert(JSON.stringify(array[0]));
ë§µìì ê°ì²´ë¥¼ í¤ë¡ ì¬ì©í ê²½ì° ìì, ë§µì´ ë©ëª¨ë¦¬ì ìë í ê°ì²´ë ë©ëª¨ë¦¬ì ë¨ìµëë¤. ê°ë¹ì§ 컬ë í°ì ëìì´ ëì§ ìì£ .
ìì:
let john = { name: "John" };
let map = new Map();
map.set(john, "...");
john = null; // 참조를 nullë¡ ë®ì´ì
// johnì ëíë´ë ê°ì²´ë ë§µ ìì ì ì¥ëì´ììµëë¤.
// map.keys()를 ì´ì©íë©´ í´ë¹ ê°ì²´ë¥¼ ì»ë ê²ë ê°ë¥í©ëë¤.
for(let obj of map.keys()){
alert(JSON.stringify(obj));
}
alert(map.size);
ì´ë° ê´ì ìì ìí¬ë§µ(WeakMap)ì ì¼ë° 맵과 ì í ë¤ë¥¸ ììì ë³´ì
ëë¤. ìí¬ë§µì ì¬ì©íë©´ í¤ë¡ ì°ì¸ ê°ì²´ê° ê°ë¹ì§ 컬ë ì
ì ëìì´ ë©ëë¤.
ìì를 ì´ì©í´ ì´ì ëí´ ìì¸í ììë³´ëë¡ í©ìë¤.
ìí¬ë§µ
맵과 ìí¬ë§µì 첫 ë²ì§¸ ì°¨ì´ë ìí¬ë§µì í¤ê° ë°ëì ê°ì²´ì¬ì¼ íë¤ë ì ì
ëë¤. ììê°ì ìí¬ë§µì í¤ê° ë ì ììµëë¤.
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "ok"); //ì ìì ì¼ë¡ ëìí©ëë¤(ê°ì²´ í¤).
// 문ìì´("test")ì í¤ë¡ ì¬ì©í ì ììµëë¤.
weakMap.set("test", "Whoops"); // Error: Invalid value used as weak map key
ìí¬ë§µì í¤ë¡ ì¬ì©ë ê°ì²´ë¥¼ 참조íë ê²ì´ ì무ê²ë ìë¤ë©´ í´ë¹ ê°ì²´ë ë©ëª¨ë¦¬ì ìí¬ë§µìì ìëì¼ë¡ ìì ë©ëë¤.
let john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // 참조를 ë®ì´ì
// johnì ëíë´ë ê°ì²´ë ì´ì ë©ëª¨ë¦¬ìì ì§ìì§ëë¤!
johnì ëíë´ë ê°ì²´ë ì¤ë¡ì§ ìí¬ë§µì í¤ë¡ë§ ì¬ì©ëê³ ìì¼ë¯ë¡, 참조를 ë®ì´ì°ê² ëë©´ ì´ ê°ì²´ë ìí¬ë§µê³¼ ë©ëª¨ë¦¬ìì ìëì¼ë¡ ìì ë©ëë¤.
맵과 ìí¬ë§µì ë ë²ì§¸ ì°¨ì´ë ìí¬ë§µì ë°ë³µ ìì
ê³¼ keys(), values(), entries() ë©ìë를 ì§ìíì§ ìëë¤ë ì ì
ëë¤. ë°ë¼ì ìí¬ë§µìì í¤ë ê° ì 체를 ì»ë ê² ë¶ê°ë¥í©ëë¤.
ìí¬ë§µì´ ì§ìíë ë©ìëë ë¨ì¶í©ëë¤.
weakMap.get(key)weakMap.set(key, value)weakMap.delete(key)weakMap.has(key)
ì ì´ë ê² ì ì ë©ìëë§ ì ê³µí ê¹ì? ìì¸ì ê°ë¹ì§ 컬ë ì
ì ëì ë°©ì ë문ì
ëë¤. ì ììì johnì ëíë´ë ê°ì²´ì²ë¼, ê°ì²´ë 모ë 참조를 ìê² ëë©´ ìëì¼ë¡ ê°ë¹ì§ 컬ë ì
ì ëìì´ ë©ëë¤. ê·¸ë°ë° ê°ë¹ì§ 컬ë ì
ì ëì ìì ì ì íí ì ì ììµëë¤.
ê°ë¹ì§ 컬ë ì
ì´ ì¼ì´ëë ìì ì ìë°ì¤í¬ë¦½í¸ ìì§ì´ ê²°ì í©ëë¤. ê°ì²´ë 모ë 참조를 ììì ë, ê·¸ ì¦ì ë©ëª¨ë¦¬ìì ìì ë ìë ìê³ , ë¤ë¥¸ ìì ìì
ì´ ìì ëê¹ì§ ë기íë¤ê° í¨ê» ìì ë ìë ììµëë¤. íì¬ ìí¬ë§µì ììê° ëª ê° ìëì§ ì íí íì
íë ê² ìì²´ê° ë¶ê°ë¥í ê²ì´ì£ . ê°ë¹ì§ 컬ë í°ê° í ë²ì ë©ëª¨ë¦¬ë¥¼ ì²ìí ìë ìê³ , ë¶ë¶ ë¶ë¶ ë©ëª¨ë¦¬ë¥¼ ì²ìí ìë ìì¼ë¯ë¡ ìí¬ë§µì ìì(í¤/ê°) ì 체를 ëìì¼ë¡ 무ì¸ê°ë¥¼ íë ë©ìëë ëì ìì²´ê° ë¶ê°ë¥í©ëë¤.
ê·¸ë¼ ìí¬ë§µì ì´ë¤ ê²½ì°ì ì¬ì©í ì ììê¹ì?
ì ì¤ ì¼ì´ì¤: ì¶ê° ë°ì´í°
ìí¬ë§µì ë¶ì°¨ì ì¸ ë°ì´í°ë¥¼ ì ì¥í ê³³ì´ íìí ë ê·¸ ì§ê°ë¥¼ ë°íí©ëë¤.
ìëíí° ë¼ì´ë¸ë¬ë¦¬ì ê°ì ì¸ë¶ ì½ëì âìíâ ê°ì²´ë¥¼ ê°ì§ê³ ìì
ì í´ì¼ íë¤ê³ ê°ì í´ ë´
ìë¤. ì´ ê°ì²´ì ë°ì´í°ë¥¼ ì¶ê°í´ì¤ì¼ íëë°, ì¶ê°í´ ì¤ ë°ì´í°ë ê°ì²´ê° ì´ììë ëììë§ ì í¨í ìí©ì
ëë¤. ì´ë´ ë ìí¬ë§µì ì¬ì©í ì ììµëë¤.
ìí¬ë§µì ìíë ë°ì´í°ë¥¼ ì ì¥íê³ , ì´ë í¤ë ê°ì²´ë¥¼ ì¬ì©íë©´ ë©ëë¤. ì´ë ê² íë©´ ê°ì²´ê° ê°ë¹ì§ 컬ë ì
ì ëìì´ ë ë, ë°ì´í°ë í¨ê» ì¬ë¼ì§ê² ë©ëë¤.
weakMap.set(john, "ë¹ë°ë¬¸ì");
// johnì´ ì¬ë§íë©´, ë¹ë°ë¬¸ìë ìëì¼ë¡ í기ë©ëë¤.
ì¢ ë 구체ì ì¸ ìì를 ë¤ì´ë³´ê² ìµëë¤.
ìëì ì¬ì©ìì 방문 íì를 ì¸ì´ 주ë ì½ëê° ììµëë¤. ê´ë ¨ ì ë³´ë ë§µì ì ì¥íê³ ìëë° ë§µ ììì í¤ì í¹ì ì¬ì©ì를 ëíë´ë ê°ì²´ë¥¼, ê°ì í´ë¹ ì¬ì©ìì 방문 íì를 ì ì¥íê³ ììµëë¤. ì´ë¤ ì¬ì©ìì ì 보를 ì ì¥í íìê° ìì´ì§ë©´(ê°ë¹ì§ 컬ë ì ì ëìì´ ëë©´) í´ë¹ ì¬ì©ìì 방문 íìë ì ì¥í íìê° ìì´ì§ ê²ëë¤.
ìë í¨ìë ë§µì ì¬ì©í´ ì¬ì©ìì 방문 íì를 ì¸ì¤ëë¤.
// ð visitsCount.js
let visitsCountMap = new Map(); // ë§µì ì¬ì©ìì 방문 íì를 ì ì¥í¨
// ì¬ì©ìê° ë°©ë¬¸íë©´ 방문 íì를 ëë ¤ì¤ëë¤.
function countUser(user) {
let count = visitsCountMap.get(user) || 0;
visitsCountMap.set(user, count + 1);
}
ìëë Johnì´ë¼ë ì¬ì©ìê° ë°©ë¬¸íì ë, ì´ë»ê² 방문 íìê° ì¦ê°íëì§ë¥¼ ë³´ì¬ì¤ëë¤.
// ð main.js
let john = { name: "John" };
countUser(john); // Johnì 방문 íì를 ì¦ê°ìíµëë¤.
// Johnì 방문 íì를 ì
íìê° ìì´ì§ë©´ ìëì ê°ì´ johnì nullë¡ ë®ì´ìëë¤.
john = null;
ì´ì johnì ëíë´ë ê°ì²´ë ê°ë¹ì§ 컬ë ì
ì ëìì´ ëì´ì¼ íëë°, visitsCountMapì í¤ë¡ ì¬ì©ëê³ ìì´ì ë©ëª¨ë¦¬ìì ìì ëì§ ììµëë¤.
í¹ì ì¬ì©ì를 ëíë´ë ê°ì²´ê° ë©ëª¨ë¦¬ìì ì¬ë¼ì§ë©´ í´ë¹ ê°ì²´ì ëí ì ë³´(방문 íì)ë ì°ë¦¬ê° ìì ì§ìì¤ì¼ íë ìí©ì
ëë¤. ì´ë ê² íì§ ìì¼ë©´ visitsCountMapê° ì°¨ì§íë ë©ëª¨ë¦¬ ê³µê°ì´ íìì´ ì»¤ì§ ê²ëë¤. ì í리ì¼ì´ì
êµ¬ì¡°ê° ë³µì¡í ë, ì´ë ê² ì¸ëª¨ ìë ë°ì´í°ë¥¼ ìëì¼ë¡ ë¹ì주ë ê² ê½¤ ê³¨ì¹ ìíëë¤.
ì´ë° 문ì ë ìí¬ë§µì ì¬ì©í´ ìë°©í ì ììµëë¤.
// ð visitsCount.js
let visitsCountMap = new WeakMap(); // ìí¬ë§µì ì¬ì©ìì 방문 íì를 ì ì¥í¨
// ì¬ì©ìê° ë°©ë¬¸íë©´ 방문 íì를 ëë ¤ì¤ëë¤.
function countUser(user) {
let count = visitsCountMap.get(user) || 0;
visitsCountMap.set(user, count + 1);
}
ìí¬ë§µì ì¬ì©í´ ì¬ì©ì 방문 íì를 ì ì¥íë©´ visitsCountMapì ìëì¼ë¡ ì²ìí´ì¤ íìê° ììµëë¤. johnì ëíë´ë ê°ì²´ê° ëë¬ ê°ë¥íì§ ìì ìíê° ëë©´ ìëì¼ë¡ ë©ëª¨ë¦¬ìì ìì ë기 ë문ì
ëë¤. ìí¬ë§µì í¤(john)ì ëìíë ê°(johnì 방문 íì)ë ìëì¼ë¡ ê°ë¹ì§ 컬ë ì
ì ëìì´ ë©ëë¤.
ì ì¤ ì¼ì´ì¤: ìºì±
ìí¬ë§µì ìºì±(caching)ì´ íìí ë ì ì©í©ëë¤. ìºì±ì ìê°ì´ ì¤ë 걸리ë ìì ì 결과를 ì ì¥í´ì ì°ì° ìê°ê³¼ ë¹ì©ì ì ì½í´ì£¼ë 기ë²ì ëë¤. ëì¼í í¨ì를 ì¬ë¬ ë² í¸ì¶í´ì¼ í ë, ìµì´ í¸ì¶ ì ë°íë ê°ì ì´ëê°ì ì ì¥í´ ëìë¤ê° ê·¸ë¤ìì í¨ì를 í¸ì¶íë ëì ì ì¥ë ê°ì ì¬ì©íë ê² ìºì±ì ì¤ë¡ì ëë¤.
ìë ììë í¨ì ì°ì° 결과를 ë§µì ì ì¥íê³ ììµëë¤.
// ð 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); // ì°ì°ì ìíí íì ìì´ ë§µì ì ì¥ë 결과를 ê°ì ¸ì¤ë©´ ë©ëë¤.
// ê°ì²´ê° ì¸ëª¨ìì´ì§ë©´ ìëì ê°ì´ nullë¡ ë®ì´ìëë¤.
obj = null;
alert(cache.size); // 1 (ì! ê·¸ë°ë° ê°ì²´ê° ì¬ì í cacheì ë¨ììë¤ì. ë©ëª¨ë¦¬ê° ëë¹ëê³ ììµëë¤.)
process(obj)를 ì¬ë¬ ë² í¸ì¶íë©´ ìµì´ í¸ì¶í ëë§ ì°ì°ì´ ìíëê³ , ê·¸ ì´íì ì°ì° 결과를 cacheìì ê°ì ¸ìµëë¤. ê·¸ë°ë° ë§µì ì¬ì©íê³ ìì´ì ê°ì²´ê° íì ìì´ì ¸ë cache를 ìëì¼ë¡ ì²ìí´ ì¤ì¼ í©ëë¤.
ë§µì ìí¬ë§µì¼ë¡ êµì²´íë©´ ì´ë° 문ì 를 ìë°©í ì ììµëë¤. ê°ì²´ê° ë©ëª¨ë¦¬ìì ìì ëë©´, ìºìì ì ì¥ë ê²°ê³¼(í¨ì ì°ì° ê²°ê³¼) ìì ë©ëª¨ë¦¬ìì ìëì¼ë¡ ìì ë기 ë문ì
ëë¤.
// ð 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);
// ê°ì²´ê° ì¸ëª¨ìì´ì§ë©´ ìëì ê°ì´ nullë¡ ë®ì´ìëë¤.
obj = null;
// ì´ ìììì ë§µì ì¬ì©í ììì²ë¼ cache.size를 ì¬ì©í ì ììµëë¤.
// íì§ë§ objê° ê°ë¹ì§ 컬ë ì
ì ëìì´ ëë¯ë¡, ìºì±ë ë°ì´í° ìì ë©ëª¨ë¦¬ìì ìì ë ê²ëë¤.
// ìì ê° ì§íëë©´ cacheì ê·¸ ì´ë¤ ììë ë¨ììì§ ììê²ëë¤.
ìí¬ì
ì´ì ìí¬ì
(WeakSet)ì ëí´ ììë´
ìë¤.
ìí¬ì ìì ê³¼ ì ì¬íë°, ê°ì²´ë§ ì ì¥í ì ìë¤ë ì ì´ ë¤ë¦ ëë¤. ììê°ì ì ì¥í ì ììµëë¤.- ì ìì ê°ì²´ë ëë¬ ê°ë¥í ëë§ ë©ëª¨ë¦¬ìì ì ì§ë©ëë¤.
ì ê³¼ ë§ì°¬ê°ì§ë¡ìí¬ì ì´ ì§ìíë ë©ìëë ë¨ì¶í©ëë¤.add,has,delete를 ì¬ì©í ì ìê³ ,size,keys()ë ë°ë³µ ìì ê´ë ¨ ë©ìëë ì¬ì©í ì ììµëë¤.
'ìí¬â맵과 ì ì¬íê² 'ìí¬âì
ë ë¶ì°¨ì ì¸ ë°ì´í°ë¥¼ ì ì¥í ë ì¬ì©í ì ììµëë¤. ë¤ë§, ìí¬ì
ì ìí¬ë§µì²ë¼ ë³µì¡í ë°ì´í°ë¥¼ ì ì¥íì§ ììµëë¤. ëì "ì"ë âìëì¤â ê°ì ê°ë¨í ëµë³ì ì»ë ì©ëë¡ ì¬ì©ë©ëë¤. ë¬¼ë¡ ìí¬ì
ì ì ì¥ëë ê°ë¤ì ê°ì²´ì´ê² ì£ .
ììì í¨ê» ìí¬ì
ì ì©ë를 ììë´
ìë¤. ìë ì½ëìì ì¬ì©ìì ì¬ì´í¸ 방문 ì¬ë¶ë¥¼ ì¶ì íë ì©ëë¡ ìí¬ì
ì ì¬ì©íê³ ììµëë¤.
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ìì johnì ëíë´ë ê°ì²´ê° ìëì¼ë¡ ìì ë©ëë¤.
ìí¬ë§µê³¼ ìí¬ì
ì ê°ì¥ í° ë¨ì ì ë°ë³µ ìì
ì´ ë¶ê°ë¥íë¤ë ì ì
ëë¤. ìí¬ë§µì´ë ìí¬ì
ì ì ì¥ë ìë£ë¥¼ í ë²ì ì»ë ê² ë¶ê°ë¥íì£ . ì´ë° ë¨ì ì ë¶í¸í¨ì ì´ëíë ê² ê°ì ë³´ì´ì§ë§, ìí¬ë§µê³¼ ìí¬ì
ì ì´ì©í´ í ì ìë 주ì ìì
ì ë°©í´íì§ ììµëë¤. ìí¬ë§µê³¼ ìí¬ì
ì ê°ì²´ì í¨ê» âì¶ê°â ë°ì´í°ë¥¼ ì ì¥íë ì©ëë¡ ì¸ ì ììµëë¤.
ìì½
ìí¬ë§µì 맵과 ì ì¬í 컬ë ì
ì
ëë¤. ìí¬ë§µì 구ì±íë ììì í¤ë ì¤ì§ ê°ì²´ë§ ê°ë¥í©ëë¤. í¤ë¡ ì¬ì©ë ê°ì²´ê° ë©ëª¨ë¦¬ìì ìì ëë©´ ì´ì ëìíë ê° ìì ìì ë©ëë¤.
ìí¬ì
ì ì
ê³¼ ì ì¬í 컬ë ì
ì
ëë¤. ìí¬ì
ì ê°ì²´ë§ ì ì¥í ì ììµëë¤. ìí¬ì
ì ì ì¥ë ê°ì²´ê° ëë¬ ë¶ê°ë¥í ìíê° ëë©´ í´ë¹ ê°ì²´ë ë©ëª¨ë¦¬ìì ìì ë©ëë¤.
ë ìë£êµ¬ì¡° 모ë êµ¬ì± ìì ì 체를 ëìì¼ë¡ íë ë©ìë를 ì§ìíì§ ììµëë¤. êµ¬ì± ìì íë를 ëìì¼ë¡ íë ë©ìëë§ ì§ìí©ëë¤.
ê°ì²´ì â주ìâ ìë£ë¥¼, ìí¬ë§µê³¼ ìí¬ì
ì âë¶ìì ì¸â ìë£ë¥¼ ì ì¥íë ííë¡ ìí¬ë§µê³¼ ìí¬ì
ì íì©í ì ììµëë¤. ê°ì²´ê° ë©ëª¨ë¦¬ìì ìì ëë©´, (ê·¸ë¦¬ê³ ì¤ë¡ì§ ìí¬ë§µê³¼ ìí¬ì
ì í¤ë§ í´ë¹ ê°ì²´ë¥¼ 참조íê³ ìë¤ë©´) ìí¬ë§µì´ë ìí¬ì
ì ì ì¥ë ì°ê´ ìë£ë¤ ìì ë©ëª¨ë¦¬ìì ìëì¼ë¡ ìì ë©ëë¤.
ëê¸
<code>í그를, ì¬ë¬ ì¤ë¡ 구ì±ë ì½ë를 ì½ì íê³ ì¶ë¤ë©´<pre>í그를 ì´ì©íì¸ì. 10ì¤ ì´ìì ì½ëë plnkr, JSBin, codepen ë±ì ìëë°ì¤ë¥¼ ì¬ì©íì¸ì.