export.js 4.5 KB

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