universal-weak-map.js

- Jump To … +
  src/tuple.js src/universal-weak-map.js src/util.js

- # universal-weak-map.js

- ¶

  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;
        }
      }