1var hasOwnProperty = Object.prototype.hasOwnProperty 2 3module.exports = PseudoMap 4 5function PseudoMap (set) { 6 if (!(this instanceof PseudoMap)) // whyyyyyyy 7 throw new TypeError("Constructor PseudoMap requires 'new'") 8 9 this.clear() 10 11 if (set) { 12 if ((set instanceof PseudoMap) || 13 (typeof Map === 'function' && set instanceof Map)) 14 set.forEach(function (value, key) { 15 this.set(key, value) 16 }, this) 17 else if (Array.isArray(set)) 18 set.forEach(function (kv) { 19 this.set(kv[0], kv[1]) 20 }, this) 21 else 22 throw new TypeError('invalid argument') 23 } 24} 25 26PseudoMap.prototype.forEach = function (fn, thisp) { 27 thisp = thisp || this 28 Object.keys(this._data).forEach(function (k) { 29 if (k !== 'size') 30 fn.call(thisp, this._data[k].value, this._data[k].key) 31 }, this) 32} 33 34PseudoMap.prototype.has = function (k) { 35 return !!find(this._data, k) 36} 37 38PseudoMap.prototype.get = function (k) { 39 var res = find(this._data, k) 40 return res && res.value 41} 42 43PseudoMap.prototype.set = function (k, v) { 44 set(this._data, k, v) 45} 46 47PseudoMap.prototype.delete = function (k) { 48 var res = find(this._data, k) 49 if (res) { 50 delete this._data[res._index] 51 this._data.size-- 52 } 53} 54 55PseudoMap.prototype.clear = function () { 56 var data = Object.create(null) 57 data.size = 0 58 59 Object.defineProperty(this, '_data', { 60 value: data, 61 enumerable: false, 62 configurable: true, 63 writable: false 64 }) 65} 66 67Object.defineProperty(PseudoMap.prototype, 'size', { 68 get: function () { 69 return this._data.size 70 }, 71 set: function (n) {}, 72 enumerable: true, 73 configurable: true 74}) 75 76PseudoMap.prototype.values = 77PseudoMap.prototype.keys = 78PseudoMap.prototype.entries = function () { 79 throw new Error('iterators are not implemented in this version') 80} 81 82// Either identical, or both NaN 83function same (a, b) { 84 return a === b || a !== a && b !== b 85} 86 87function Entry (k, v, i) { 88 this.key = k 89 this.value = v 90 this._index = i 91} 92 93function find (data, k) { 94 for (var i = 0, s = '_' + k, key = s; 95 hasOwnProperty.call(data, key); 96 key = s + i++) { 97 if (same(data[key].key, k)) 98 return data[key] 99 } 100} 101 102function set (data, k, v) { 103 for (var i = 0, s = '_' + k, key = s; 104 hasOwnProperty.call(data, key); 105 key = s + i++) { 106 if (same(data[key].key, k)) { 107 data[key].value = v 108 return 109 } 110 } 111 data.size++ 112 data[key] = new Entry(k, v, key) 113} 114