javascript / expert
Snippet
Symbol-Keyed WeakMap Isolation for Custom Directive Instances
Custom directives attached to DOM elements can lead to memory leaks if event handlers are stored directly on element properties. Storing state in a module-scoped WeakMap with Symbol keys ensures garbage collection compatibility and strict out-of-band property isolation.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const INSTANCE_KEY = Symbol('directive_state');const stateStore = new WeakMap();export const vSecureClick = {mounted(el, binding) {const handler = (event) => {if (!el.contains(event.target)) return;binding.value(event);};stateStore.set(el, { [INSTANCE_KEY]: handler });document.addEventListener('click', handler, true);},unmounted(el) {const state = stateStore.get(el);if (state && state[INSTANCE_KEY]) {document.removeEventListener('click', state[INSTANCE_KEY], true);stateStore.delete(el);}}};
vue
Breakdown
1
const INSTANCE_KEY = Symbol('directive_state');
Creates a unique Symbol key to prevent property collision on private state objects.
2
const stateStore = new WeakMap();
Holds DOM element references weakly to enable automatic memory reclamation when element unmounts.
3
stateStore.set(el, { [INSTANCE_KEY]: handler });
Associates the directive handler state with the DOM element strictly out-of-band.
4
document.removeEventListener('click', state[INSTANCE_KEY], true);
Cleans up capture-phase event listeners on unmount to prevent dangling memory references.