假设有任意变量,定义如下:
var a = function() {/* Statements */};
我想要一个函数来检查变量的类型是否为类函数。例如:
function foo(v) {if (v is function type?) {/* do something */}};
foo(a);
我怎样才能检查变量a是否为上述定义的函数类型?
假设有任意变量,定义如下:
var a = function() {/* Statements */};
我想要一个函数来检查变量的类型是否为类函数。例如:
function foo(v) {if (v is function type?) {/* do something */}};
foo(a);
我怎样才能检查变量a是否为上述定义的函数类型?
当前回答
如果你使用Lodash,你可以用_.isFunction来实现。
_.isFunction(function(){});
// => true
_.isFunction(/abc/);
// => false
_.isFunction(true);
// => false
_.isFunction(null);
// => false
如果value是一个函数,该方法返回true,否则返回false。
其他回答
有几种方法,所以我将把它们都总结一下
Best way is: function foo(v) {if (v instanceof Function) {/* do something */} }; Most performant (no string comparison) and elegant solution - the instanceof operator has been supported in browsers for a very long time, so don't worry - it will work in IE 6. Next best way is: function foo(v) {if (typeof v === "function") {/* do something */} }; disadvantage of typeof is that it is susceptible to silent failure, bad, so if you have a typo (e.g. "finction") - in this case the if will just return false and you won't know you have an error until later in your code The next best way is: function isFunction(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; } This has no advantage over solution #1 or #2 but is a lot less readable. An improved version of this is function isFunction(x) { return Object.prototype.toString.call(x) == '[object Function]'; } but still lot less semantic than solution #1
另一种简单的方法:
var fn = function () {}
if (fn.constructor === Function) {
// true
} else {
// false
}
js使用了一个更精细但高性能的测试:
_.isFunction = function(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
};
参见:https://jsben.ch/B6h73
编辑:更新的测试表明typeof可能更快,参见https://jsben.ch/B6h73
我认为你可以在Function原型上定义一个标志,然后检查你想测试的实例是否继承了这个标志
定义一个标志:
Function.prototype.isFunction = true;
然后检查它是否存在
var foo = function(){};
foo.isFunction; // will return true
缺点是,另一个原型可以定义相同的标志,然后它是没有价值的,但如果你可以完全控制所包含的模块,这是最简单的方法
当然,下划线的方式更有效率,但当效率不是问题时,最好的检查方法是在@Paul Rosania的下划线页面上写的。
受下划线的启发,最后的isFunction函数如下:
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}
注意:此解决方案不适用于异步函数、生成器或代理函数。请参阅其他答案,以了解更多最新的解决方案。