You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.6 KiB
JavaScript
83 lines
2.6 KiB
JavaScript
'use strict';
|
|
var redefineAll = require('./_redefine-all')
|
|
, getWeak = require('./_meta').getWeak
|
|
, anObject = require('./_an-object')
|
|
, isObject = require('./_is-object')
|
|
, anInstance = require('./_an-instance')
|
|
, forOf = require('./_for-of')
|
|
, createArrayMethod = require('./_array-methods')
|
|
, $has = require('./_has')
|
|
, arrayFind = createArrayMethod(5)
|
|
, arrayFindIndex = createArrayMethod(6)
|
|
, id = 0;
|
|
|
|
// fallback for uncaught frozen keys
|
|
var uncaughtFrozenStore = function(that){
|
|
return that._l || (that._l = new UncaughtFrozenStore);
|
|
};
|
|
var UncaughtFrozenStore = function(){
|
|
this.a = [];
|
|
};
|
|
var findUncaughtFrozen = function(store, key){
|
|
return arrayFind(store.a, function(it){
|
|
return it[0] === key;
|
|
});
|
|
};
|
|
UncaughtFrozenStore.prototype = {
|
|
get: function(key){
|
|
var entry = findUncaughtFrozen(this, key);
|
|
if(entry)return entry[1];
|
|
},
|
|
has: function(key){
|
|
return !!findUncaughtFrozen(this, key);
|
|
},
|
|
set: function(key, value){
|
|
var entry = findUncaughtFrozen(this, key);
|
|
if(entry)entry[1] = value;
|
|
else this.a.push([key, value]);
|
|
},
|
|
'delete': function(key){
|
|
var index = arrayFindIndex(this.a, function(it){
|
|
return it[0] === key;
|
|
});
|
|
if(~index)this.a.splice(index, 1);
|
|
return !!~index;
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
|
|
var C = wrapper(function(that, iterable){
|
|
anInstance(that, C, NAME, '_i');
|
|
that._i = id++; // collection id
|
|
that._l = undefined; // leak store for uncaught frozen objects
|
|
if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
|
|
});
|
|
redefineAll(C.prototype, {
|
|
// 23.3.3.2 WeakMap.prototype.delete(key)
|
|
// 23.4.3.3 WeakSet.prototype.delete(value)
|
|
'delete': function(key){
|
|
if(!isObject(key))return false;
|
|
var data = getWeak(key);
|
|
if(data === true)return uncaughtFrozenStore(this)['delete'](key);
|
|
return data && $has(data, this._i) && delete data[this._i];
|
|
},
|
|
// 23.3.3.4 WeakMap.prototype.has(key)
|
|
// 23.4.3.4 WeakSet.prototype.has(value)
|
|
has: function has(key){
|
|
if(!isObject(key))return false;
|
|
var data = getWeak(key);
|
|
if(data === true)return uncaughtFrozenStore(this).has(key);
|
|
return data && $has(data, this._i);
|
|
}
|
|
});
|
|
return C;
|
|
},
|
|
def: function(that, key, value){
|
|
var data = getWeak(anObject(key), true);
|
|
if(data === true)uncaughtFrozenStore(that).set(key, value);
|
|
else data[that._i] = value;
|
|
return that;
|
|
},
|
|
ufstore: uncaughtFrozenStore
|
|
}; |