internal-metadata.js 2.7 KB

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