91 lines
2.8 KiB
JavaScript
91 lines
2.8 KiB
JavaScript
'use strict';
|
|
var $ = require('../internals/export');
|
|
var uncurryThis = require('../internals/function-uncurry-this');
|
|
var hiddenKeys = require('../internals/hidden-keys');
|
|
var isObject = require('../internals/is-object');
|
|
var hasOwn = require('../internals/has-own-property');
|
|
var defineProperty = require('../internals/object-define-property').f;
|
|
var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');
|
|
var getOwnPropertyNamesExternalModule = require('../internals/object-get-own-property-names-external');
|
|
var isExtensible = require('../internals/object-is-extensible');
|
|
var uid = require('../internals/uid');
|
|
var FREEZING = require('../internals/freezing');
|
|
|
|
var REQUIRED = false;
|
|
var METADATA = uid('meta');
|
|
var id = 0;
|
|
|
|
var setMetadata = function (it) {
|
|
defineProperty(it, METADATA, { value: {
|
|
objectID: 'O' + id++, // object ID
|
|
weakData: {} // weak collections IDs
|
|
} });
|
|
};
|
|
|
|
var fastKey = function (it, create) {
|
|
// return a primitive with prefix
|
|
if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
|
|
if (!hasOwn(it, METADATA)) {
|
|
// 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
|
|
setMetadata(it);
|
|
// return object ID
|
|
} return it[METADATA].objectID;
|
|
};
|
|
|
|
var getWeakData = function (it, create) {
|
|
if (!hasOwn(it, METADATA)) {
|
|
// 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
|
|
setMetadata(it);
|
|
// return the store of weak collections IDs
|
|
} return it[METADATA].weakData;
|
|
};
|
|
|
|
// add metadata on freeze-family methods calling
|
|
var onFreeze = function (it) {
|
|
if (FREEZING && REQUIRED && isExtensible(it) && !hasOwn(it, METADATA)) setMetadata(it);
|
|
return it;
|
|
};
|
|
|
|
var enable = function () {
|
|
meta.enable = function () { /* empty */ };
|
|
REQUIRED = true;
|
|
var getOwnPropertyNames = getOwnPropertyNamesModule.f;
|
|
var splice = uncurryThis([].splice);
|
|
var test = {};
|
|
test[METADATA] = 1;
|
|
|
|
// prevent exposing of metadata key
|
|
if (getOwnPropertyNames(test).length) {
|
|
getOwnPropertyNamesModule.f = function (it) {
|
|
var result = getOwnPropertyNames(it);
|
|
for (var i = 0, length = result.length; i < length; i++) {
|
|
if (result[i] === METADATA) {
|
|
splice(result, i, 1);
|
|
break;
|
|
}
|
|
} return result;
|
|
};
|
|
|
|
$({ target: 'Object', stat: true, forced: true }, {
|
|
getOwnPropertyNames: getOwnPropertyNamesExternalModule.f
|
|
});
|
|
}
|
|
};
|
|
|
|
var meta = module.exports = {
|
|
enable: enable,
|
|
fastKey: fastKey,
|
|
getWeakData: getWeakData,
|
|
onFreeze: onFreeze
|
|
};
|
|
|
|
hiddenKeys[METADATA] = true;
|