You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.8 KiB
89 lines
2.8 KiB
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;
|
|
|