_meta.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. var META = require('./_uid')('meta');
  2. var isObject = require('./_is-object');
  3. var has = require('./_has');
  4. var setDesc = require('./_object-dp').f;
  5. var id = 0;
  6. var isExtensible = Object.isExtensible || function () {
  7. return true;
  8. };
  9. var FREEZE = !require('./_fails')(function () {
  10. return isExtensible(Object.preventExtensions({}));
  11. });
  12. var setMeta = function (it) {
  13. setDesc(it, META, { value: {
  14. i: 'O' + ++id, // object ID
  15. w: {} // weak collections IDs
  16. } });
  17. };
  18. var fastKey = function (it, create) {
  19. // return primitive with prefix
  20. if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  21. if (!has(it, META)) {
  22. // can't set metadata to uncaught frozen object
  23. if (!isExtensible(it)) return 'F';
  24. // not necessary to add metadata
  25. if (!create) return 'E';
  26. // add missing metadata
  27. setMeta(it);
  28. // return object ID
  29. } return it[META].i;
  30. };
  31. var getWeak = function (it, create) {
  32. if (!has(it, META)) {
  33. // can't set metadata to uncaught frozen object
  34. if (!isExtensible(it)) return true;
  35. // not necessary to add metadata
  36. if (!create) return false;
  37. // add missing metadata
  38. setMeta(it);
  39. // return hash weak collections IDs
  40. } return it[META].w;
  41. };
  42. // add metadata on freeze-family methods calling
  43. var onFreeze = function (it) {
  44. if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);
  45. return it;
  46. };
  47. var meta = module.exports = {
  48. KEY: META,
  49. NEED: false,
  50. fastKey: fastKey,
  51. getWeak: getWeak,
  52. onFreeze: onFreeze
  53. };