is-constructor.js 1.8 KB

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