polyfill.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. 'use strict';
  2. var clear = require('es5-ext/array/#/clear')
  3. , eIndexOf = require('es5-ext/array/#/e-index-of')
  4. , setPrototypeOf = require('es5-ext/object/set-prototype-of')
  5. , callable = require('es5-ext/object/valid-callable')
  6. , validValue = require('es5-ext/object/valid-value')
  7. , d = require('d')
  8. , ee = require('event-emitter')
  9. , Symbol = require('es6-symbol')
  10. , iterator = require('es6-iterator/valid-iterable')
  11. , forOf = require('es6-iterator/for-of')
  12. , Iterator = require('./lib/iterator')
  13. , isNative = require('./is-native-implemented')
  14. , call = Function.prototype.call
  15. , defineProperties = Object.defineProperties, getPrototypeOf = Object.getPrototypeOf
  16. , MapPoly;
  17. module.exports = MapPoly = function (/*iterable*/) {
  18. var iterable = arguments[0], keys, values, self;
  19. if (!(this instanceof MapPoly)) throw new TypeError('Constructor requires \'new\'');
  20. if (isNative && setPrototypeOf && (Map !== MapPoly)) {
  21. self = setPrototypeOf(new Map(), getPrototypeOf(this));
  22. } else {
  23. self = this;
  24. }
  25. if (iterable != null) iterator(iterable);
  26. defineProperties(self, {
  27. __mapKeysData__: d('c', keys = []),
  28. __mapValuesData__: d('c', values = [])
  29. });
  30. if (!iterable) return self;
  31. forOf(iterable, function (value) {
  32. var key = validValue(value)[0];
  33. value = value[1];
  34. if (eIndexOf.call(keys, key) !== -1) return;
  35. keys.push(key);
  36. values.push(value);
  37. }, self);
  38. return self;
  39. };
  40. if (isNative) {
  41. if (setPrototypeOf) setPrototypeOf(MapPoly, Map);
  42. MapPoly.prototype = Object.create(Map.prototype, {
  43. constructor: d(MapPoly)
  44. });
  45. }
  46. ee(defineProperties(MapPoly.prototype, {
  47. clear: d(function () {
  48. if (!this.__mapKeysData__.length) return;
  49. clear.call(this.__mapKeysData__);
  50. clear.call(this.__mapValuesData__);
  51. this.emit('_clear');
  52. }),
  53. delete: d(function (key) {
  54. var index = eIndexOf.call(this.__mapKeysData__, key);
  55. if (index === -1) return false;
  56. this.__mapKeysData__.splice(index, 1);
  57. this.__mapValuesData__.splice(index, 1);
  58. this.emit('_delete', index, key);
  59. return true;
  60. }),
  61. entries: d(function () { return new Iterator(this, 'key+value'); }),
  62. forEach: d(function (cb/*, thisArg*/) {
  63. var thisArg = arguments[1], iterator, result;
  64. callable(cb);
  65. iterator = this.entries();
  66. result = iterator._next();
  67. while (result !== undefined) {
  68. call.call(cb, thisArg, this.__mapValuesData__[result],
  69. this.__mapKeysData__[result], this);
  70. result = iterator._next();
  71. }
  72. }),
  73. get: d(function (key) {
  74. var index = eIndexOf.call(this.__mapKeysData__, key);
  75. if (index === -1) return;
  76. return this.__mapValuesData__[index];
  77. }),
  78. has: d(function (key) {
  79. return (eIndexOf.call(this.__mapKeysData__, key) !== -1);
  80. }),
  81. keys: d(function () { return new Iterator(this, 'key'); }),
  82. set: d(function (key, value) {
  83. var index = eIndexOf.call(this.__mapKeysData__, key), emit;
  84. if (index === -1) {
  85. index = this.__mapKeysData__.push(key) - 1;
  86. emit = true;
  87. }
  88. this.__mapValuesData__[index] = value;
  89. if (emit) this.emit('_add', index, key);
  90. return this;
  91. }),
  92. size: d.gs(function () { return this.__mapKeysData__.length; }),
  93. values: d(function () { return new Iterator(this, 'value'); }),
  94. toString: d(function () { return '[object Map]'; })
  95. }));
  96. Object.defineProperty(MapPoly.prototype, Symbol.iterator, d(function () {
  97. return this.entries();
  98. }));
  99. Object.defineProperty(MapPoly.prototype, Symbol.toStringTag, d('c', 'Map'));