var hasOwnProperty = Object.prototype.hasOwnProperty module.exports = PseudoMap function PseudoMap (set) { if (!(this instanceof PseudoMap)) // whyyyyyyy throw new TypeError("Constructor PseudoMap requires 'new'") this.clear() if (set) { if ((set instanceof PseudoMap) || (typeof Map === 'function' && set instanceof Map)) set.forEach(function (value, key) { this.set(key, value) }, this) else if (Array.isArray(set)) set.forEach(function (kv) { this.set(kv[0], kv[1]) }, this) else throw new TypeError('invalid argument') } } PseudoMap.prototype.forEach = function (fn, thisp) { thisp = thisp || this Object.keys(this._data).forEach(function (k) { if (k !== 'size') fn.call(thisp, this._data[k].value, this._data[k].key) }, this) } PseudoMap.prototype.has = function (k) { return !!find(this._data, k) } PseudoMap.prototype.get = function (k) { var res = find(this._data, k) return res && res.value } PseudoMap.prototype.set = function (k, v) { set(this._data, k, v) } PseudoMap.prototype.delete = function (k) { var res = find(this._data, k) if (res) { delete this._data[res._index] this._data.size-- } } PseudoMap.prototype.clear = function () { var data = Object.create(null) data.size = 0 Object.defineProperty(this, '_data', { value: data, enumerable: false, configurable: true, writable: false }) } Object.defineProperty(PseudoMap.prototype, 'size', { get: function () { return this._data.size }, set: function (n) {}, enumerable: true, configurable: true }) PseudoMap.prototype.values = PseudoMap.prototype.keys = PseudoMap.prototype.entries = function () { throw new Error('iterators are not implemented in this version') } // Either identical, or both NaN function same (a, b) { return a === b || a !== a && b !== b } function Entry (k, v, i) { this.key = k this.value = v this._index = i } function find (data, k) { for (var i = 0, s = '_' + k, key = s; hasOwnProperty.call(data, key); key = s + i++) { if (same(data[key].key, k)) return data[key] } } function set (data, k, v) { for (var i = 0, s = '_' + k, key = s; hasOwnProperty.call(data, key); key = s + i++) { if (same(data[key].key, k)) { data[key].value = v return } } data.size++ data[key] = new Entry(k, v, key) }