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