es.reflect.construct.js 2.2 KB

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