is-constructor.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. 'use strict';
  2. var uncurryThis = require('../internals/function-uncurry-this');
  3. var fails = require('../internals/fails');
  4. var isCallable = require('../internals/is-callable');
  5. var classof = require('../internals/classof');
  6. var getBuiltIn = require('../internals/get-built-in');
  7. var inspectSource = require('../internals/inspect-source');
  8. var noop = function () { /* empty */ };
  9. var empty = [];
  10. var construct = getBuiltIn('Reflect', 'construct');
  11. var constructorRegExp = /^\s*(?:class|function)\b/;
  12. var exec = uncurryThis(constructorRegExp.exec);
  13. var INCORRECT_TO_STRING = !constructorRegExp.test(noop);
  14. var isConstructorModern = function isConstructor(argument) {
  15. if (!isCallable(argument)) return false;
  16. try {
  17. construct(noop, empty, argument);
  18. return true;
  19. } catch (error) {
  20. return false;
  21. }
  22. };
  23. var isConstructorLegacy = function isConstructor(argument) {
  24. if (!isCallable(argument)) return false;
  25. switch (classof(argument)) {
  26. case 'AsyncFunction':
  27. case 'GeneratorFunction':
  28. case 'AsyncGeneratorFunction': return false;
  29. }
  30. try {
  31. // we can't check .prototype since constructors produced by .bind haven't it
  32. // `Function#toString` throws on some built-it function in some legacy engines
  33. // (for example, `DOMQuad` and similar in FF41-)
  34. return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument));
  35. } catch (error) {
  36. return true;
  37. }
  38. };
  39. isConstructorLegacy.sham = true;
  40. // `IsConstructor` abstract operation
  41. // https://tc39.es/ecma262/#sec-isconstructor
  42. module.exports = !construct || fails(function () {
  43. var called;
  44. return isConstructorModern(isConstructorModern.call)
  45. || !isConstructorModern(Object)
  46. || !isConstructorModern(function () { called = true; })
  47. || called;
  48. }) ? isConstructorLegacy : isConstructorModern;