index.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. 'use strict';
  2. var fnToStr = Function.prototype.toString;
  3. var reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;
  4. var badArrayLike;
  5. var isCallableMarker;
  6. if (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {
  7. try {
  8. badArrayLike = Object.defineProperty({}, 'length', {
  9. get: function () {
  10. throw isCallableMarker;
  11. }
  12. });
  13. isCallableMarker = {};
  14. // eslint-disable-next-line no-throw-literal
  15. reflectApply(function () { throw 42; }, null, badArrayLike);
  16. } catch (_) {
  17. if (_ !== isCallableMarker) {
  18. reflectApply = null;
  19. }
  20. }
  21. } else {
  22. reflectApply = null;
  23. }
  24. var constructorRegex = /^\s*class\b/;
  25. var isES6ClassFn = function isES6ClassFunction(value) {
  26. try {
  27. var fnStr = fnToStr.call(value);
  28. return constructorRegex.test(fnStr);
  29. } catch (e) {
  30. return false; // not a function
  31. }
  32. };
  33. var tryFunctionObject = function tryFunctionToStr(value) {
  34. try {
  35. if (isES6ClassFn(value)) { return false; }
  36. fnToStr.call(value);
  37. return true;
  38. } catch (e) {
  39. return false;
  40. }
  41. };
  42. var toStr = Object.prototype.toString;
  43. var fnClass = '[object Function]';
  44. var genClass = '[object GeneratorFunction]';
  45. var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
  46. /* globals document: false */
  47. var documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {};
  48. module.exports = reflectApply
  49. ? function isCallable(value) {
  50. if (value === documentDotAll) { return true; }
  51. if (!value) { return false; }
  52. if (typeof value !== 'function' && typeof value !== 'object') { return false; }
  53. if (typeof value === 'function' && !value.prototype) { return true; }
  54. try {
  55. reflectApply(value, null, badArrayLike);
  56. } catch (e) {
  57. if (e !== isCallableMarker) { return false; }
  58. }
  59. return !isES6ClassFn(value);
  60. }
  61. : function isCallable(value) {
  62. if (value === documentDotAll) { return true; }
  63. if (!value) { return false; }
  64. if (typeof value !== 'function' && typeof value !== 'object') { return false; }
  65. if (typeof value === 'function' && !value.prototype) { return true; }
  66. if (hasToStringTag) { return tryFunctionObject(value); }
  67. if (isES6ClassFn(value)) { return false; }
  68. var strClass = toStr.call(value);
  69. return strClass === fnClass || strClass === genClass;
  70. };