export class UniversalWeakMap {
constructor() {
A map data structure that holds object keys weakly, yet can also hold
non-object keys, unlike the native WeakMap
.
export class UniversalWeakMap {
constructor() {
Since a WeakMap
cannot hold primitive values as keys, we need a
backup Map
instance to hold primitive keys. Both this._weakMap
and this._strongMap
are lazily initialized.
this._weakMap = null;
this._strongMap = null;
}
Since get
and set
are the only methods used, that’s all I’ve
implemented here.
get(key) {
const map = this._getMap(key, false);
if (map) {
return map.get(key);
}
}
set(key, value) {
this._getMap(key, true).set(key, value);
An actual Map
or WeakMap
would return this
here, but
returning the value
is more convenient for the tuple
implementation.
return value;
}
_getMap(key, canCreate) {
if (! canCreate) {
return isObjRef(key) ? this._weakMap : this._strongMap;
}
if (isObjRef(key)) {
return this._weakMap || (this._weakMap = new WeakMap);
}
return this._strongMap || (this._strongMap = new Map);
}
}
function isObjRef(value) {
switch (typeof value) {
case "object":
if (value === null) {
return false;
}
case "function":
return true;
default:
return false;
}
}