| var META = require('./_uid')('meta') |
| , isObject = require('./_is-object') |
| , has = require('./_has') |
| , setDesc = require('./_object-dp').f |
| , id = 0; |
| var isExtensible = Object.isExtensible || function(){ |
| return true; |
| }; |
| var FREEZE = !require('./_fails')(function(){ |
| return isExtensible(Object.preventExtensions({})); |
| }); |
| var setMeta = function(it){ |
| setDesc(it, META, {value: { |
| i: 'O' + ++id, // object ID |
| w: {} // weak collections IDs |
| }}); |
| }; |
| var fastKey = function(it, create){ |
| // return primitive with prefix |
| if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; |
| if(!has(it, META)){ |
| // can't set metadata to uncaught frozen object |
| if(!isExtensible(it))return 'F'; |
| // not necessary to add metadata |
| if(!create)return 'E'; |
| // add missing metadata |
| setMeta(it); |
| // return object ID |
| } return it[META].i; |
| }; |
| var getWeak = function(it, create){ |
| if(!has(it, META)){ |
| // can't set metadata to uncaught frozen object |
| if(!isExtensible(it))return true; |
| // not necessary to add metadata |
| if(!create)return false; |
| // add missing metadata |
| setMeta(it); |
| // return hash weak collections IDs |
| } return it[META].w; |
| }; |
| // add metadata on freeze-family methods calling |
| var onFreeze = function(it){ |
| if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it); |
| return it; |
| }; |
| var meta = module.exports = { |
| KEY: META, |
| NEED: false, |
| fastKey: fastKey, |
| getWeak: getWeak, |
| onFreeze: onFreeze |
| }; |