es.reflect.construct.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. 'use strict';
  2. var $ = require('../internals/export');
  3. var getBuiltIn = require('../internals/get-built-in');
  4. var apply = require('../internals/function-apply');
  5. var bind = require('../internals/function-bind');
  6. var aConstructor = require('../internals/a-constructor');
  7. var anObject = require('../internals/an-object');
  8. var isObject = require('../internals/is-object');
  9. var create = require('../internals/object-create');
  10. var fails = require('../internals/fails');
  11. var nativeConstruct = getBuiltIn('Reflect', 'construct');
  12. var ObjectPrototype = Object.prototype;
  13. var push = [].push;
  14. // `Reflect.construct` method
  15. // https://tc39.es/ecma262/#sec-reflect.construct
  16. // MS Edge supports only 2 arguments and argumentsList argument is optional
  17. // FF Nightly sets third argument as `new.target`, but does not create `this` from it
  18. var NEW_TARGET_BUG = fails(function () {
  19. function F() { /* empty */ }
  20. return !(nativeConstruct(function () { /* empty */ }, [], F) instanceof F);
  21. });
  22. var ARGS_BUG = !fails(function () {
  23. nativeConstruct(function () { /* empty */ });
  24. });
  25. var FORCED = NEW_TARGET_BUG || ARGS_BUG;
  26. $({ target: 'Reflect', stat: true, forced: FORCED, sham: FORCED }, {
  27. construct: function construct(Target, args /* , newTarget */) {
  28. aConstructor(Target);
  29. anObject(args);
  30. var newTarget = arguments.length < 3 ? Target : aConstructor(arguments[2]);
  31. if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget);
  32. if (Target === newTarget) {
  33. // w/o altered newTarget, optimization for 0-4 arguments
  34. switch (args.length) {
  35. case 0: return new Target();
  36. case 1: return new Target(args[0]);
  37. case 2: return new Target(args[0], args[1]);
  38. case 3: return new Target(args[0], args[1], args[2]);
  39. case 4: return new Target(args[0], args[1], args[2], args[3]);
  40. }
  41. // w/o altered newTarget, lot of arguments case
  42. var $args = [null];
  43. apply(push, $args, args);
  44. return new (apply(bind, Target, $args))();
  45. }
  46. // with altered newTarget, not support built-in constructors
  47. var proto = newTarget.prototype;
  48. var instance = create(isObject(proto) ? proto : ObjectPrototype);
  49. var result = apply(Target, instance, args);
  50. return isObject(result) ? result : instance;
  51. }
  52. });