我如何检查一个JavaScriptvariables是否是函数types?

假设我有任何variables,定义如下:

var a = function() {/* Statements */}; 

我想要一个函数来检查variables的types是否类似于函数。 即:

 function foo(v) {if (v is function type?) {/* do something */}}; foo(a); 

我怎样才能检查variables“a”是否是上面定义的types的函数?

当然下划线的方法更有效率,但是当效率不是问题时,最好的方法是写在@Paul Rosania链接的下划线页面上。

受到下划线的启发,最后的函数function如下:

 function isFunction(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; } 
 if (typeof v === "function") { // do something } 

Underscore.js使用更精细但性能更高的testing:

 _.isFunction = function(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); }; 

请参阅: http : //jsperf.com/alternative-isfunction-implementations

编辑:更新的testing表明typeof可能会更快,请参阅http://jsperf.com/alternative-isfunction-implementations/4

有几种方法,我会总结一下

  1. 最好的方法是:
    
    函数foo(v){if(v instanceof Function){/ * do something * /}};
    
    

    性能最高(没有string比较)和优雅的解决scheme – instanceof运算符已经在浏览器中支持了很长时间,所以不用担心 – 它将在IE 6中工作。

  2. 下一个最好的方法是:
    
    函数foo(v){if(typeof v ===“function”){/ * do something * /}};
    
    

    typeof缺点是易受沉默失败的影响,所以如果你有一个错字(例如“finction”) – 在这种情况下,if语句只会返回false,直到后来你才会知道错误在你的代码中

  3. 下一个最好的方法是:
    
    函数isFunction(functionToCheck){
         var getType = {};
         return functionToCheck && getType.toString.call(functionToCheck)==='[object Function]';
     }
    
    

    这与解决scheme#1或#2没有任何优势,但可读性较差。 这是一个改进版本

    
    函数isFunction(x){
        返回Object.prototype.toString.call(x)=='[object Function]';
     }
    
    

    但仍然比解决scheme#1的语义less得多

@grandecomplex:你的解决scheme有相当多的冗长。 如果写成这样会更清楚些:

 function isFunction(x) { return Object.prototype.toString.call(x) == '[object Function]'; } 
 var foo = function(){}; if (typeof foo === "function") { alert("is function") } 

如果你使用jQuery,你可以使用isFunction:

 $.isFunction(functionName); 

参考

尝试instanceof:看来所有的函数都inheritance自“Function”类:

 // Test data var f1 = function () { alert("test"); } var o1 = { Name: "Object_1" }; F_est = function () { }; var o2 = new F_est(); // Results alert(f1 instanceof Function); // true alert(o1 instanceof Function); // false alert(o2 instanceof Function); // false 

另一种简单的方法是:

 var fn = function () {} if (fn.constructor === Function) { // true } else { // false } 

我发现在IE8中testing原生浏览器function时,使用toStringinstanceoftypeof不起作用。 这里是一个在IE8中正常工作的方法(据我所知):

 function isFn(f){ return !!(f && f.call && f.apply); } //Returns true in IE7/8 isFn(document.getElementById); 

或者,您可以使用以下方法检查本机function:

 "getElementById" in document 

尽pipe如此,我已经在某个地方看到,这在IE7及以下版本中并不总是适用。

从节点v0.11开始,你可以使用标准的util函数:

 var util = require('util'); util.isFunction('foo'); 

我想你可以在Function原型上定义一个标志,并检查你想testing的实例是否inheritance了这个标志

定义一个标志:

 Function.prototype.isFunction = true; 

然后检查它是否存在

 var foo = function(){}; foo.isFunction; // will return true 

缺点是另一个原型可以定义相同的标志,然后它是毫无价值的,但是如果你完全控制包含的模块,这是最简单的方法

如果你使用Lodash,你可以用_.isFunction来完成。

 _.isFunction(function(){}); // => true _.isFunction(/abc/); // => false _.isFunction(true); // => false _.isFunction(null); // => false 

如果value是一个函数,则此方法返回true ,否则返回false

以下似乎也为我工作(从node.jstesting):

 var isFunction = function(o) { return Function.prototype.isPrototypeOf(o); }; console.log(isFunction(function(){})); // true console.log(isFunction({})); // false 

你应该在js中使用typeOf运算符

 var a=function(){ alert("fun a"); } alert(typeof a);// alerts "function" 

一些以前的答案显示的解决scheme是使用typeof。 以下是代码片段在NodeJs中,

  function startx() { console.log("startx function called."); } var fct= {}; fct["/startx"] = startx; if (typeof fct[/startx] === 'function') { //check if function then execute it fct[/startx](); }