export.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. 'use strict';
  2. var globalThis = require('../internals/global-this');
  3. var apply = require('../internals/function-apply');
  4. var uncurryThis = require('../internals/function-uncurry-this-clause');
  5. var isCallable = require('../internals/is-callable');
  6. var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;
  7. var isForced = require('../internals/is-forced');
  8. var path = require('../internals/path');
  9. var bind = require('../internals/function-bind-context');
  10. var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
  11. var hasOwn = require('../internals/has-own-property');
  12. // add debugging info
  13. require('../internals/shared-store');
  14. var wrapConstructor = function (NativeConstructor) {
  15. var Wrapper = function (a, b, c) {
  16. if (this instanceof Wrapper) {
  17. switch (arguments.length) {
  18. case 0: return new NativeConstructor();
  19. case 1: return new NativeConstructor(a);
  20. case 2: return new NativeConstructor(a, b);
  21. } return new NativeConstructor(a, b, c);
  22. } return apply(NativeConstructor, this, arguments);
  23. };
  24. Wrapper.prototype = NativeConstructor.prototype;
  25. return Wrapper;
  26. };
  27. /*
  28. options.target - name of the target object
  29. options.global - target is the global object
  30. options.stat - export as static methods of target
  31. options.proto - export as prototype methods of target
  32. options.real - real prototype method for the `pure` version
  33. options.forced - export even if the native feature is available
  34. options.bind - bind methods to the target, required for the `pure` version
  35. options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
  36. options.unsafe - use the simple assignment of property instead of delete + defineProperty
  37. options.sham - add a flag to not completely full polyfills
  38. options.enumerable - export as enumerable property
  39. options.dontCallGetSet - prevent calling a getter on target
  40. options.name - the .name of the function if it does not match the key
  41. */
  42. module.exports = function (options, source) {
  43. var TARGET = options.target;
  44. var GLOBAL = options.global;
  45. var STATIC = options.stat;
  46. var PROTO = options.proto;
  47. var nativeSource = GLOBAL ? globalThis : STATIC ? globalThis[TARGET] : globalThis[TARGET] && globalThis[TARGET].prototype;
  48. var target = GLOBAL ? path : path[TARGET] || createNonEnumerableProperty(path, TARGET, {})[TARGET];
  49. var targetPrototype = target.prototype;
  50. var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE;
  51. var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor;
  52. for (key in source) {
  53. FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
  54. // contains in native
  55. USE_NATIVE = !FORCED && nativeSource && hasOwn(nativeSource, key);
  56. targetProperty = target[key];
  57. if (USE_NATIVE) if (options.dontCallGetSet) {
  58. descriptor = getOwnPropertyDescriptor(nativeSource, key);
  59. nativeProperty = descriptor && descriptor.value;
  60. } else nativeProperty = nativeSource[key];
  61. // export native or implementation
  62. sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key];
  63. if (!FORCED && !PROTO && typeof targetProperty == typeof sourceProperty) continue;
  64. // bind methods to global for calling from export context
  65. if (options.bind && USE_NATIVE) resultProperty = bind(sourceProperty, globalThis);
  66. // wrap global constructors for prevent changes in this version
  67. else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty);
  68. // make static versions for prototype methods
  69. else if (PROTO && isCallable(sourceProperty)) resultProperty = uncurryThis(sourceProperty);
  70. // default case
  71. else resultProperty = sourceProperty;
  72. // add a flag to not completely full polyfills
  73. if (options.sham || (sourceProperty && sourceProperty.sham) || (targetProperty && targetProperty.sham)) {
  74. createNonEnumerableProperty(resultProperty, 'sham', true);
  75. }
  76. createNonEnumerableProperty(target, key, resultProperty);
  77. if (PROTO) {
  78. VIRTUAL_PROTOTYPE = TARGET + 'Prototype';
  79. if (!hasOwn(path, VIRTUAL_PROTOTYPE)) {
  80. createNonEnumerableProperty(path, VIRTUAL_PROTOTYPE, {});
  81. }
  82. // export virtual prototype methods
  83. createNonEnumerableProperty(path[VIRTUAL_PROTOTYPE], key, sourceProperty);
  84. // export real prototype methods
  85. if (options.real && targetPrototype && (FORCED || !targetPrototype[key])) {
  86. createNonEnumerableProperty(targetPrototype, key, sourceProperty);
  87. }
  88. }
  89. }
  90. };