1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- 'use strict';
- var hide = require('./$.hide')
- , redefineAll = require('./$.redefine-all')
- , anObject = require('./$.an-object')
- , isObject = require('./$.is-object')
- , strictNew = require('./$.strict-new')
- , forOf = require('./$.for-of')
- , createArrayMethod = require('./$.array-methods')
- , $has = require('./$.has')
- , WEAK = require('./$.uid')('weak')
- , isExtensible = Object.isExtensible || isObject
- , arrayFind = createArrayMethod(5)
- , arrayFindIndex = createArrayMethod(6)
- , id = 0;
- // fallback for frozen keys
- var frozenStore = function(that){
- return that._l || (that._l = new FrozenStore);
- };
- var FrozenStore = function(){
- this.a = [];
- };
- var findFrozen = function(store, key){
- return arrayFind(store.a, function(it){
- return it[0] === key;
- });
- };
- FrozenStore.prototype = {
- get: function(key){
- var entry = findFrozen(this, key);
- if(entry)return entry[1];
- },
- has: function(key){
- return !!findFrozen(this, key);
- },
- set: function(key, value){
- var entry = findFrozen(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){
- strictNew(that, C, NAME);
- that._i = id++; // collection id
- that._l = undefined; // leak store for 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;
- if(!isExtensible(key))return frozenStore(this)['delete'](key);
- return $has(key, WEAK) && $has(key[WEAK], this._i) && delete key[WEAK][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;
- if(!isExtensible(key))return frozenStore(this).has(key);
- return $has(key, WEAK) && $has(key[WEAK], this._i);
- }
- });
- return C;
- },
- def: function(that, key, value){
- if(!isExtensible(anObject(key))){
- frozenStore(that).set(key, value);
- } else {
- $has(key, WEAK) || hide(key, WEAK, {});
- key[WEAK][that._i] = value;
- } return that;
- },
- frozenStore: frozenStore,
- WEAK: WEAK
- };
|