UNPKG

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