_collection-weak.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. 'use strict';
  2. var redefineAll = require('./_redefine-all')
  3. , getWeak = require('./_meta').getWeak
  4. , anObject = require('./_an-object')
  5. , isObject = require('./_is-object')
  6. , anInstance = require('./_an-instance')
  7. , forOf = require('./_for-of')
  8. , createArrayMethod = require('./_array-methods')
  9. , $has = require('./_has')
  10. , arrayFind = createArrayMethod(5)
  11. , arrayFindIndex = createArrayMethod(6)
  12. , id = 0;
  13. // fallback for uncaught frozen keys
  14. var uncaughtFrozenStore = function(that){
  15. return that._l || (that._l = new UncaughtFrozenStore);
  16. };
  17. var UncaughtFrozenStore = function(){
  18. this.a = [];
  19. };
  20. var findUncaughtFrozen = function(store, key){
  21. return arrayFind(store.a, function(it){
  22. return it[0] === key;
  23. });
  24. };
  25. UncaughtFrozenStore.prototype = {
  26. get: function(key){
  27. var entry = findUncaughtFrozen(this, key);
  28. if(entry)return entry[1];
  29. },
  30. has: function(key){
  31. return !!findUncaughtFrozen(this, key);
  32. },
  33. set: function(key, value){
  34. var entry = findUncaughtFrozen(this, key);
  35. if(entry)entry[1] = value;
  36. else this.a.push([key, value]);
  37. },
  38. 'delete': function(key){
  39. var index = arrayFindIndex(this.a, function(it){
  40. return it[0] === key;
  41. });
  42. if(~index)this.a.splice(index, 1);
  43. return !!~index;
  44. }
  45. };
  46. module.exports = {
  47. getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
  48. var C = wrapper(function(that, iterable){
  49. anInstance(that, C, NAME, '_i');
  50. that._i = id++; // collection id
  51. that._l = undefined; // leak store for uncaught frozen objects
  52. if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
  53. });
  54. redefineAll(C.prototype, {
  55. // 23.3.3.2 WeakMap.prototype.delete(key)
  56. // 23.4.3.3 WeakSet.prototype.delete(value)
  57. 'delete': function(key){
  58. if(!isObject(key))return false;
  59. var data = getWeak(key);
  60. if(data === true)return uncaughtFrozenStore(this)['delete'](key);
  61. return data && $has(data, this._i) && delete data[this._i];
  62. },
  63. // 23.3.3.4 WeakMap.prototype.has(key)
  64. // 23.4.3.4 WeakSet.prototype.has(value)
  65. has: function has(key){
  66. if(!isObject(key))return false;
  67. var data = getWeak(key);
  68. if(data === true)return uncaughtFrozenStore(this).has(key);
  69. return data && $has(data, this._i);
  70. }
  71. });
  72. return C;
  73. },
  74. def: function(that, key, value){
  75. var data = getWeak(anObject(key), true);
  76. if(data === true)uncaughtFrozenStore(that).set(key, value);
  77. else data[that._i] = value;
  78. return that;
  79. },
  80. ufstore: uncaughtFrozenStore
  81. };