| 'use strict'; |
| |
| var fnToStr = Function.prototype.toString; |
| |
| var constructorRegex = /^\s*class\b/; |
| var isES6ClassFn = function isES6ClassFunction(value) { |
| try { |
| var fnStr = fnToStr.call(value); |
| return constructorRegex.test(fnStr); |
| } catch (e) { |
| return false; // not a function |
| } |
| }; |
| |
| var tryFunctionObject = function tryFunctionToStr(value) { |
| try { |
| if (isES6ClassFn(value)) { return false; } |
| fnToStr.call(value); |
| return true; |
| } catch (e) { |
| return false; |
| } |
| }; |
| var toStr = Object.prototype.toString; |
| var fnClass = '[object Function]'; |
| var genClass = '[object GeneratorFunction]'; |
| var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; |
| |
| module.exports = function isCallable(value) { |
| if (!value) { return false; } |
| if (typeof value !== 'function' && typeof value !== 'object') { return false; } |
| if (typeof value === 'function' && !value.prototype) { return true; } |
| if (hasToStringTag) { return tryFunctionObject(value); } |
| if (isES6ClassFn(value)) { return false; } |
| var strClass = toStr.call(value); |
| return strClass === fnClass || strClass === genClass; |
| }; |