Skip to content

Instantly share code, notes, and snippets.

@Rowadz
Last active September 26, 2022 12:26
Show Gist options
  • Save Rowadz/43ba90ed43544f6ff2a671ed11e8f318 to your computer and use it in GitHub Desktop.
Save Rowadz/43ba90ed43544f6ff2a671ed11e8f318 to your computer and use it in GitHub Desktop.
A map object that keeps the object references event if you try to override them.
const refKeeperMapFactory = (() => {
type RefMap = Map<string, Record<string, any>>
let refKeeper: RefMap
return () => {
if (refKeeper) {
return refKeeper
}
const mapProxyHandler = {
get(target: RefMap, name: string) {
const functionOrValue = Reflect.get(target, name)
const isFunction = typeof functionOrValue === 'function'
if (isFunction && name === 'set') {
const mapSet: RefMap['set'] = functionOrValue
return (key: string, value: Record<string, any>) =>
target.has(key) ? target : mapSet.call(target, key, value)
} else if (isFunction) {
return functionOrValue.bind(target)
}
return functionOrValue
},
}
refKeeper = new Proxy(new Map(), mapProxyHandler)
return refKeeper
}
})()
const refKeeper = refKeeperMapFactory()
refKeeper.set('a', { a: '1', sayHi: () => 'HI!' })
const oldRef = refKeeper.get('a')
refKeeper.set('a', { mySet: new Set([1, 2]) })
const oldRef2 = refKeeper.get('a')
refKeeper.set('a', { myObj: {} })
console.log(
'Still holding the same ref?',
Object.is(oldRef, oldRef2),
'Size',
refKeeper.size
)
const newRefKeeper = refKeeperMapFactory()
newRefKeeper.delete('a')
console.log(
'Still using the same ref keeper?',
Object.is(newRefKeeper, refKeeper),
'Size',
newRefKeeper.size
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment