Javascript:给出的函数为空?

Mar*_*era 17 javascript

我们有一个函数调用

function doSomethingAndInvokeCallback(callback){
    // do something
    callback();
}
Run Code Online (Sandbox Code Playgroud)

我可以检查给定的参数是否有效 if(typeof callback == 'function')

如果给定回调函数是函数且不为空,我怎么才能发现?

喜欢

doSomethingAndInvokeCallback(function(){
    //nothing here
})
Run Code Online (Sandbox Code Playgroud)

Jam*_*ers 7

看来你可以定义一个函数来检索函数体(1).我写了一个小的(非权威的)测试:

http://jsfiddle.net/6qn5P/

Function.prototype.getBody =
  function() {
    // Get content between first { and last }
    var m = this.toString().match(/\{([\s\S]*)\}/m)[1];
    // Strip comments
    return m.replace(/^\s*\/\/.*$/mg,'');
  };

function foo() {
    var a = 1, b = "bar";
    alert(b + a);
    return null;
}

console.log(foo.getBody());
console.log(foo.getBody().length);
Run Code Online (Sandbox Code Playgroud)


jfr*_*d00 7

没有完全可靠的方法来知道函数是否为空,因为JS中有多种函数,一些用JS实现,一些用本机代码实现,你无法确定传入的函数是否有任何作用.如果要将传入函数限制为仅非常简单的JS函数,可以使用其他答案中概述的机制(检查函数的来源).但是,除了严格控制的情况之外,我不建议这样做,因为有很多合法的javascript方法可以打破这种情况.

我建议您应该更改函数参数的约定并让调用者传递null或不传递任何东西(这将产生参数undefined)而不是空函数.然后,很清楚他们是否打算有一个被调用的函数.如果它们然后传递一个空函数而不是null或undefined,它们将获得函数接口指定的行为.调用者可以选择所需的行为,您可以以更安全的方式实现您的功能.

此外,你的问题中的一个主要假设是不对的.您无法安全地使用typeof x == "function"来确定某些功能是否在某些类型的功能中在某些旧版本的IE中无法可靠地运行.如果你想学习如何检测某些东西是否是一个函数,你可以在这里学习jQuery(即使你没有使用它).jQuery有一个函数,它在内部使用的所有时间jQuery.isFunction()都返回一个bool.它主要用于测试参数以查看是否传递了函数.

在内部,它调用:

Object.prototype.toString.call(o)
Run Code Online (Sandbox Code Playgroud)

然后检查结果.如果结果中包含"Function",则测试参数是一个函数.

因此,使用jQuery中使用的相同技术,您可以构建自己的简单小isFunction例程,如下所示:

function isFunction(test) {
    return(Object.prototype.toString.call(test).indexOf("Function") > -1);
}
Run Code Online (Sandbox Code Playgroud)

当然,如果你有jQuery可用,你可以使用它自己的版本:

jQuery.isFunction(o)
Run Code Online (Sandbox Code Playgroud)

如果对潜在的跨浏览器兼容性问题存在疑问,我会发现它有助于了解其中一个大型库如何解决问题,即使您不打算使用该库也是如此.您可以确定这些库已针对许多浏览器进行了审查,因此他们使用的技术是安全的.你有时必须解开他们可能用来弄清楚他们真正在做什么的所有内部例程(这个功能就是这种情况),但是你可以节省很多腿部工作.

你可以在这里看到一个工作试验台:http://jsfiddle.net/jfriend00/PKcsM/

在现代浏览器中typeof fn === "function",但是在旧版本的IE中,一些函数给出了一个原因typeof === "object",这可能是jQuery使用这种在旧版IE中工作的其他方法的原因.


pim*_*vdb 5

一种可能性是将.toString结果与正则表达式匹配以获取函数体,然后修剪以检查它是否已成为空字符串:

var f = function foo()    { 


};

/^function [^(]*\(\)[ ]*{(.*)}$/.exec(
     f.toString().replace(/\n/g, "")
)[1].trim() === ""; // true
Run Code Online (Sandbox Code Playgroud)

那个丑陋的正则表达式确实处理了命名函数周围的空格以及名称和左大括号之前的无关空格。像 infoo ()这样的空间似乎被删除了,所以没有理由检查这些。