You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.3 KiB
74 lines
2.3 KiB
'use strict'; |
|
|
|
var fnToStr = Function.prototype.toString; |
|
var reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply; |
|
var badArrayLike; |
|
var isCallableMarker; |
|
if (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') { |
|
try { |
|
badArrayLike = Object.defineProperty({}, 'length', { |
|
get: function () { |
|
throw isCallableMarker; |
|
} |
|
}); |
|
isCallableMarker = {}; |
|
// eslint-disable-next-line no-throw-literal |
|
reflectApply(function () { throw 42; }, null, badArrayLike); |
|
} catch (_) { |
|
if (_ !== isCallableMarker) { |
|
reflectApply = null; |
|
} |
|
} |
|
} else { |
|
reflectApply = null; |
|
} |
|
|
|
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' && !!Symbol.toStringTag; // better: use `has-tostringtag` |
|
/* globals document: false */ |
|
var documentDotAll = typeof document === 'object' && typeof document.all === 'undefined' && document.all !== undefined ? document.all : {}; |
|
|
|
module.exports = reflectApply |
|
? function isCallable(value) { |
|
if (value === documentDotAll) { return true; } |
|
if (!value) { return false; } |
|
if (typeof value !== 'function' && typeof value !== 'object') { return false; } |
|
if (typeof value === 'function' && !value.prototype) { return true; } |
|
try { |
|
reflectApply(value, null, badArrayLike); |
|
} catch (e) { |
|
if (e !== isCallableMarker) { return false; } |
|
} |
|
return !isES6ClassFn(value); |
|
} |
|
: function isCallable(value) { |
|
if (value === documentDotAll) { return true; } |
|
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; |
|
};
|
|
|