2013-05-03 23 views
18

Ho attraversato un JavaScript library che implementa un cross-browser WeakMap in ES5. (WeakMap è previsto per ES6.)Implementazione WeakMap in EcmaScript5?

Come è possibile che questo funzioni senza supporto nel linguaggio JavaScript stesso?

Edit: Giusto per essere chiari, mi riferisco a un debole Mappa, non un regolare Map. Ho testato questo progetto usando il profiler di Chrome e le chiavi non sono tenute da riferimenti forti. Ottengono GC senza doverli rimuovere da WeakMap.

+3

Considera di studiare il codice sorgente. –

+3

@squint Sta facendo qualcosa di abbastanza profondo, non riesco a capire come non abbia un forte riferimento ai tasti. Ad esempio, non usa Array. – paleozogt

+3

WeakMaps sono una funzionalità ES6 che consente di associare i dati a un oggetto, ma consente comunque di raccogliere i dati quando si trova l'oggetto, OPPURE l'istanza WeakMap è raccolta automaticamente. È impossibile fare entrambe queste cose senza supporto linguistico. La maggior parte degli shocks di WeakMap ignorano la parte relativa alla possibilità che i dati vengano convertiti in GC quando l'istanza WeakMap è GC. – AgentME

risposta

26

Mi ci è voluto un po 'per ingannare il codice, ma poi mi ha colpito: la chiave stessa è utilizzata per memorizzare un riferimento al valore.

Ad esempio, diversi livelli in set fa

defProp(obj, globalID, { value: store }); 

dove defProp è stato definito per essere Object.defineProperty, obj è la chiave, globalID è un GUID e store è un oggetto di archiviazione che contiene il valore.

Poi giù in get Sembra il valore con

obj[globalID];

Questo è molto intelligente. La WeakMap in realtà non contiene un riferimento a qualcosa (debole o altro) - semplicemente imposta una politica su dove memorizzare segretamente il valore. L'uso di Object.defineProperty significa che non scoprirai casualmente la memorizzazione del valore-- devi conoscere il magic guid per cercarlo.

Poiché la chiave si riferisce direttamente al valore (e WeakMap non si riferisce ad esso), quando tutti i riferimenti alla chiave sono andati, ottiene GCed come normale.

+0

Se 'obj' è la chiave WeakMap, e' globalID' è definita su 'obj', mi chiedo perché il' globalID' non appare quando si usa 'Object.getOwnPropertyNames()'. –

+2

mi stavo chiedendo lo stesso; peccato che la libertà sia così lontana da essere praticamente illeggibile. ci deve essere una spiegazione più semplice ... – dandavis

+0

capito: i cheat di lib: definisce nuovamente Object.getOwnPropertyNames(). boo per passare alle funzioni native esistenti. – dandavis