| var META = require('./_uid')('meta'); |
| var isObject = require('./_is-object'); |
| var has = require('./_has'); |
| var setDesc = require('./_object-dp').f; |
| var 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 |
| }; |