es.reflect.construct.js 2.1 KB

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