1 'use strict'; 2 3 var fnToStr = Function.prototype.toString; 4 5 var constructorRegex = /^\s*class\b/; 6 var isES6ClassFn = function isES6ClassFunction(value) { 7 try { 8 var fnStr = fnToStr.call(value); 9 return constructorRegex.test(fnStr); 10 } catch (e) { 11 return false; // not a function 12 } 13 }; 14 15 var tryFunctionObject = function tryFunctionToStr(value) { 16 try { 17 if (isES6ClassFn(value)) { return false; } 18 fnToStr.call(value); 19 return true; 20 } catch (e) { 21 return false; 22 } 23 }; 24 var toStr = Object.prototype.toString; 25 var fnClass = '[object Function]'; 26 var genClass = '[object GeneratorFunction]'; 27 var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; 28 29 module.exports = function isCallable(value) { 30 if (!value) { return false; } 31 if (typeof value !== 'function' && typeof value !== 'object') { return false; } 32 if (typeof value === 'function' && !value.prototype) { return true; } 33 if (hasToStringTag) { return tryFunctionObject(value); } 34 if (isES6ClassFn(value)) { return false; } 35 var strClass = toStr.call(value); 36 return strClass === fnClass || strClass === genClass; 37 }; 38