首页 文章

如何检查javascript变量是否为函数类型?

提问于
浏览
709

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

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

我想要一个函数来检查变量的类型是否像函数一样 . 即:

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

如何以上面定义的方式检查变量'a'是否为类型函数?

17 回答

  • 21
    var foo = function(){};
    if (typeof foo === "function") {
      alert("is function")
    }
    
  • 3

    我发现在IE8中测试本机浏览器功能时,使用 toStringinstanceoftypeof 不起作用 . 这是一个在IE8中工作正常的方法(据我所知):

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

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

    "getElementById" in document
    

    虽然,我已经在某处读过,这在IE7及以下版本中并不总是有效 .

  • 46

    有几种方法可以总结它们

    • 最好的方法是:
    function foo(v) {if (v instanceof Function) {/* do something */} };
    

    性能最佳(没有字符串比较)和优雅的解决方案 - 在浏览器中支持instanceof运算符很长一段时间,所以不要担心 - 它将在IE 6中运行 .

    • 下一个最好的方法是:
    function foo(v) {if (typeof v === "function") {/* do something */} };
    

    typeof 的缺点是它容易出现静音失败,不好,所以如果你有一个拼写错误(例如"finction") - 在这种情况下,if只会返回false并且你不会认识你在您的代码中稍后会出现错误

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

    这没有解决方案#1或#2的优势,但可读性差得多 . 这方面的改进版本是

    function isFunction(x) {
        return Object.prototype.toString.call(x) == '[object Function]';
    }
    

    ,但仍然比解决方案#1少得多

  • 5
    if (typeof v === "function") {
        // do something
    }
    
  • 72

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

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

    见:http://jsperf.com/alternative-isfunction-implementations

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

  • 1360

    jQuery (自版本3.3起不推荐使用)Reference

    $.isFunction(functionName);
    

    AngularJS Reference

    angular.isFunction(value);
    

    Lodash Reference

    _.isFunction(value);
    

    Underscore Reference

    _.isFunction(object);
    

    Node.js 自v4.0.0以来已弃用Reference

    var util = require('util');
    util.isFunction(object);
    
  • 84

    以前的一些答案显示的解决方案是使用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]();
      }
    
  • 4

    以下似乎也适合我(从 node.js 测试):

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

    对于那些对函数风格感兴趣的人,或者想要在元编程中使用更具表现力的方法(例如类型检查),看到Ramda库来完成这样的任务可能会很有趣 .

    下一个代码只包含pure和pointfree函数:

    const R = require('ramda');
    
    const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
    
    const equalsSyncFunction = isPrototypeEquals(() => {});
    
    const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
    

    从ES2017开始, async 函数可用,因此我们也可以检查它们:

    const equalsAsyncFunction = isPrototypeEquals(async () => {});
    
    const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
    

    然后将它们组合在一起:

    const isFunction = R.either(isSyncFunction, isAsyncFunction);
    

    当然,应该保护函数不受 nullundefined 值的影响,所以要使其成为"safe":

    const safeIsFunction = R.unless(R.isNil, isFunction);
    

    并且,完整的摘要总结:

    const R = require('ramda');
    
    const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
    
    const equalsSyncFunction = isPrototypeEquals(() => {});
    const equalsAsyncFunction = isPrototypeEquals(async () => {});
    
    const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
    const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
    
    const isFunction = R.either(isSyncFunction, isAsyncFunction);
    
    const safeIsFunction = R.unless(R.isNil, isFunction);
    
    // ---
    
    console.log(safeIsFunction( function () {} ));
    console.log(safeIsFunction( () => {} ));
    console.log(safeIsFunction( (async () => {}) ));
    console.log(safeIsFunction( new class {} ));
    console.log(safeIsFunction( {} ));
    console.log(safeIsFunction( [] ));
    console.log(safeIsFunction( 'a' ));
    console.log(safeIsFunction( 1 ));
    console.log(safeIsFunction( null ));
    console.log(safeIsFunction( undefined ));
    

    但是,请注意,由于大量使用高阶函数,此解决方案可能会显示出比其他可用选项更低的性能 .

  • 7

    我认为您可以在Function原型上定义一个标志,并检查您要测试的实例是否继承了该标志

    define a flag:

    Function.prototype.isFunction = true;
    

    and then check if it exist

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

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

  • 54

    另一个简单的方法:

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

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

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

    @grandecomplex:你的解决方案有相当多的冗长 . 如果这样写的话会更清楚:

    function isFunction(x) {
      return Object.prototype.toString.call(x) == '[object Function]';
    }
    
  • 4

    如果你使用Lodash,你可以使用_.isFunction .

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

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

  • 11

    尝试instanceof:似乎所有函数都继承自“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
    
  • 0

    确定下划线的方式更有效,但是当效率不是问题时,检查的最佳方法是在@Paul Rosania链接的下划线页面上编写 .

    灵感来自下划线,最终的isFunction函数如下:

    function isFunction(functionToCheck) {
     return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
    }
    
  • 303

    你应该在js中使用 typeOf operator .

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

相关问题