internal-metadata.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. var $ = require('../internals/export');
  2. var uncurryThis = require('../internals/function-uncurry-this');
  3. var hiddenKeys = require('../internals/hidden-keys');
  4. var isObject = require('../internals/is-object');
  5. var hasOwn = require('../internals/has-own-property');
  6. var defineProperty = require('../internals/object-define-property').f;
  7. var getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');
  8. var getOwnPropertyNamesExternalModule = require('../internals/object-get-own-property-names-external');
  9. var isExtensible = require('../internals/object-is-extensible');
  10. var uid = require('../internals/uid');
  11. var FREEZING = require('../internals/freezing');
  12. var REQUIRED = false;
  13. var METADATA = uid('meta');
  14. var id = 0;
  15. var setMetadata = function (it) {
  16. defineProperty(it, METADATA, { value: {
  17. objectID: 'O' + id++, // object ID
  18. weakData: {} // weak collections IDs
  19. } });
  20. };
  21. var fastKey = function (it, create) {
  22. // return a primitive with prefix
  23. if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  24. if (!hasOwn(it, METADATA)) {
  25. // can't set metadata to uncaught frozen object
  26. if (!isExtensible(it)) return 'F';
  27. // not necessary to add metadata
  28. if (!create) return 'E';
  29. // add missing metadata
  30. setMetadata(it);
  31. // return object ID
  32. } return it[METADATA].objectID;
  33. };
  34. var getWeakData = function (it, create) {
  35. if (!hasOwn(it, METADATA)) {
  36. // can't set metadata to uncaught frozen object
  37. if (!isExtensible(it)) return true;
  38. // not necessary to add metadata
  39. if (!create) return false;
  40. // add missing metadata
  41. setMetadata(it);
  42. // return the store of weak collections IDs
  43. } return it[METADATA].weakData;
  44. };
  45. // add metadata on freeze-family methods calling
  46. var onFreeze = function (it) {
  47. if (FREEZING && REQUIRED && isExtensible(it) && !hasOwn(it, METADATA)) setMetadata(it);
  48. return it;
  49. };
  50. var enable = function () {
  51. meta.enable = function () { /* empty */ };
  52. REQUIRED = true;
  53. var getOwnPropertyNames = getOwnPropertyNamesModule.f;
  54. var splice = uncurryThis([].splice);
  55. var test = {};
  56. test[METADATA] = 1;
  57. // prevent exposing of metadata key
  58. if (getOwnPropertyNames(test).length) {
  59. getOwnPropertyNamesModule.f = function (it) {
  60. var result = getOwnPropertyNames(it);
  61. for (var i = 0, length = result.length; i < length; i++) {
  62. if (result[i] === METADATA) {
  63. splice(result, i, 1);
  64. break;
  65. }
  66. } return result;
  67. };
  68. $({ target: 'Object', stat: true, forced: true }, {
  69. getOwnPropertyNames: getOwnPropertyNamesExternalModule.f
  70. });
  71. }
  72. };
  73. var meta = module.exports = {
  74. enable: enable,
  75. fastKey: fastKey,
  76. getWeakData: getWeakData,
  77. onFreeze: onFreeze
  78. };
  79. hiddenKeys[METADATA] = true;