Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active October 8, 2015 01:01
Show Gist options
  • Save WebReflection/0e193457312b269ce1c4 to your computer and use it in GitHub Desktop.
Save WebReflection/0e193457312b269ce1c4 to your computer and use it in GitHub Desktop.
Symbol based WeakMap
var WeakMap = WeakMap || (function (s, dP, hOP) {'use strict';
function WeakMap() { // by Andrea Giammarchi - WTFPL
dP(this, s, {value: Symbol('WeakMap')});
}
WeakMap.prototype = {
'delete': function del(o) {
delete o[this[s]];
},
get: function get(o) {
return o[this[s]];
},
has: function has(o) {
return hOP.call(o, this[s]);
},
set: function set(o, v) {
dP(o, this[s], {configurable: true, value: v});
}
};
return WeakMap;
}(Symbol('WeakMap'), Object.defineProperty, {}.hasOwnProperty));
@WebReflection
Copy link
Author

The following version has a fallback for non extensible objects.

var WeakMap = WeakMap || (function (O) {
  'use strict'; // (C) Andrea Giammarchi - Mit Style License
  var
    hOP = O.hasOwnProperty,
    dP = O.defineProperty,
    iE = O.isExtensible,
    s = Symbol('WeakMap')
  ;
  return O.defineProperties(
    (function WeakMap() {
      dP(this, s, {value: Symbol('WeakMap')});
      dP(this, 'k', {value: []});
      dP(this, 'v', {value: []});
    }).prototype, {
    'delete': {value: function del(o) {
      if (iE(o)) {
        delete o[this[s]];
      } else {
        var i = this.k.indexOf(o);
        if (-1 < i) {
          this.k.splice(i, 1);
          this.v.splice(i, 1);
        }
      }
    }},
    get: {value: function get(o) {
      return iE(o) ? o[this[s]] : this.v[this.k.indexOf(o)];
    }},
    has: {value: function has(o) {
      return iE(o) ?
        hOP.call(o, this[s]) :
        -1 < this.k.indexOf(o);
    }},
    set: {value: function set(o, v) {
      if (iE(o)) {
        // the Symbol needs to be set as non enumerable
        // otherwise it might leak through Object.assign
        dP(o, this[s], {configurable: true, value: v});
      } else {
        var i = this.k.indexOf(o);
        this.v[
          i < 0 ? (this.k.push(o) - 1) : i
        ] = v;
      }
    }}
  }).constructor;
}(Object));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment