在es5-shim.js上,我已经看到以下代码来创建isCallable()
函数:
// Having a toString local variable name breaks in Opera so use to_string.
var to_string = ObjectPrototype.toString;
/* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
var isCallable; /* inlined from https://npmjs.com/is-callable */
var fnToStr = Function.prototype.toString,
constructorRegex = /^\s*class /,
isES6ClassFn = function isES6ClassFn(value) {
try {
var fnStr = fnToStr.call(value);
var singleStripped = fnStr.replace(/\/\/.*\n/g, '');
var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, '');
var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' ');
return constructorRegex.test(spaceStripped);
} catch (e) { return false; /* not a function */ }
},
tryFunctionObject = function tryFunctionObject(value) {
try {
if (isES6ClassFn(value)) { return false; }
fnToStr.call(value); return true;
} catch (e) { return false; } },
isCallable = function isCallable(value) {
if (!value) { return false; }
if (typeof value !== 'function' && typeof value !== 'object') { return false; }
if (hasToStringTag) { return tryFunctionObject(value); }
if (isES6ClassFn(value)) { return false; }
var strClass = to_string.call(value);
return strClass === '[object Function]' || strClass === '[object GeneratorFunction]';
};
即使我知道V8中功能正常的RegExp
typeof
错误以及其他一些错误,这似乎也不必要地复杂。 (这是之后我清理了一些变量!)
为什么不做这样的检查:
function isCallable(obj) {
return (typeof obj === 'function' && obj.call === Function.prototype.call)
}
为什么要经历所有其他检查的麻烦?