54 lines
1.5 KiB
JavaScript
54 lines
1.5 KiB
JavaScript
|
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
|
||
|
};
|