我如何检查一个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
有几种方法,我会总结一下
- 最好的方法是:
函数foo(v){if(v instanceof Function){/ * do something * /}};
性能最高(没有string比较)和优雅的解决scheme – instanceof运算符已经在浏览器中支持了很长时间,所以不用担心 – 它将在IE 6中工作。
- 下一个最好的方法是:
函数foo(v){if(typeof v ===“function”){/ * do something * /}};
typeof
缺点是易受沉默失败的影响,所以如果你有一个错字(例如“finction”) – 在这种情况下,if语句只会返回false,直到后来你才会知道错误在你的代码中 - 下一个最好的方法是:
函数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时,使用toString
, instanceof
和typeof
不起作用。 这里是一个在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.js
testing):
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](); }