让我们进行一次函数调用
function doSomethingAndInvokeCallback(callback){
// do something
callback();
}
我可以检查给定的参数是否为函数:if(typeof callback == 'function')
如何判断给定的回调函数是函数且不为空?
例如:
doSomethingAndInvokeCallback(function(){
//nothing here
})
让我们进行一次函数调用
function doSomethingAndInvokeCallback(callback){
// do something
callback();
}
我可以检查给定的参数是否为函数:if(typeof callback == 'function')
如何判断给定的回调函数是函数且不为空?
例如:
doSomethingAndInvokeCallback(function(){
//nothing here
})
typeof x == "function"
来确定某个东西是否为函数,因为在某些旧版本的IE中,对于某些类型的函数,这种方法不可靠。 如果您想学习如何检测某个东西是否为函数,则可以从jQuery这里进行学习(即使您不使用它)。 jQuery有一个它一直在内部使用的函数,称为jQuery.isFunction()
,它返回一个布尔值。 它主要用于测试参数以查看是否传递了函数。Object.prototype.toString.call(o)
然后检查结果。如果结果中有"Function",则测试参数是一个函数。
因此,使用jQuery中使用的相同技术,您可以构建自己的简单的isFunction
程序,如下所示:
function isFunction(test) {
return(Object.prototype.toString.call(test).indexOf("Function") > -1);
}
jQuery.isFunction(o)
typeof fn === "function"
,但在旧版本的IE中,一些函数会给出typeof === "object"
,这可能是jQuery使用此其他方法的原因,该方法在这些旧版本的IE中有效。Object.prototype.toString.call(alert) === "[object Object]"
,因此它仍然不是完全可靠的。 - pimvdb看起来你可以定义一个函数来检索另一个函数的主体(1)。 我编写了一个小型(非确定性)测试:
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);
一种可能性是将.toString
的结果与正则表达式进行匹配,以获取函数体,并进行修剪以检查它是否变为空字符串:
var f = function foo() {
};
/^function [^(]*\(\)[ ]*{(.*)}$/.exec(
f.toString().replace(/\n/g, "")
)[1].trim() === ""; // true
foo ()
中的空格似乎已被删除,因此不需要检查这些内容。您可能可以通过.toString()
获得此信息:
var blank = function(){};
var f = function(){};
var f2 = function() { return 1; };
f.toString() == blank.toString(); // true
f2.toString() == blank.toString(); // false
但是这种方法非常容易出错:
var blank = function(){};
var f = function(){ }; // extra space!
f.toString() == blank.toString(); // false
您可以对字符串进行一些修改来尝试克服这个问题,但我怀疑这非常依赖于浏览器。如果我是您,我不会在生产环境中尝试这样做。即使您规范了空格,它仍然无法捕捉其他无操作行,包括注释、无用的var
语句等。要真正解决这些问题,您可能需要一个完整的标记系统(或一个疯狂的正则表达式)。
对于主机函数,您无法这样做,但对于其他函数,您可以相当可靠地执行此操作。
function isEmpty(f) {
return typeof f === "function" &&
/^function[^{]*[{]\s*[}]\s*$/.test(
Function.prototype.toString.call(f));
}
这并不高效,但是主要的解释器在函数中实现了toString
,虽然它不适用于某些空函数的一些解释器。
function () { /* nothing here */ }
function () { ; }
function () { return; }
var foo = function(){ /* Comment */ };
alert(foo.toString());
NodeJS v0.10.28
和 Google Chrome 浏览器上进行了测试。输出结果为 'function (){ /* Comment */ }'
。我认为,在这些环境下无法正常工作。 - gihanchanuka