假设我有任何变量,定义如下:
var a = function() {/* Statements */};
我想要一个函数来检查变量的类型是否类似于函数。即:
function foo(v) {if (v is function type?) {/* do something */}};
foo(a);
如何以上面定义的方式检查变量a
是否为Function
类型?
答案 0 :(得分:1471)
if (typeof v === "function") {
// do something
}
答案 1 :(得分:328)
确定下划线的方式更有效,但是当效率不成问题时,检查的最佳方法是写在由@Paul Rosania链接的下划线页面上。
受下划线的启发,最终的isFunction函数如下:
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}
答案 2 :(得分:124)
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
答案 3 :(得分:89)
有几种方法可以概括所有
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少得多的语义
答案 4 :(得分:75)
jQuery (自3.3版以来已弃用)Reference
$.isFunction(functionName);
AngularJS Reference
angular.isFunction(value);
Lodash Reference
_.isFunction(value);
下划线 Reference
_.isFunction(object);
自v4.0.0以来,Node.js 已弃用Reference
var util = require('util');
util.isFunction(object);
答案 5 :(得分:54)
@grandecomplex:你的解决方案有相当多的冗长。如果这样写的话会更清楚:
function isFunction(x) {
return Object.prototype.toString.call(x) == '[object Function]';
}
答案 6 :(得分:46)
var foo = function(){};
if (typeof foo === "function") {
alert("is function")
}
答案 7 :(得分:27)
尝试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
答案 8 :(得分:11)
另一种简单的方式:
var fn = function () {}
if (fn.constructor === Function) {
// true
} else {
// false
}
答案 9 :(得分:8)
对于那些对功能样式感兴趣的人,或者在元编程中寻找更具表现力的方法(例如类型检查),看到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);
当然,应该保护功能免受null
和undefined
值的影响,以便使其安全":
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 ));
但请注意,由于大量使用高阶函数,此解决方案可能会显示出比其他可用选项更低的性能。
答案 10 :(得分:7)
具有更多浏览器支持并且还包含异步功能的内容可能是:
const isFunction = value => value && (Object.prototype.toString.call(value) === "[object Function]" || "function" === typeof value || value instanceof Function);
然后像这样测试它:
isFunction(isFunction); //true
isFunction(function(){}); //true
isFunction(()=> {}); //true
isFunction(()=> {return 1}); //true
isFunction(async function asyncFunction(){}); //true
isFunction(Array); //true
isFunction(Date); //true
isFunction(Object); //true
isFunction(Number); //true
isFunction(String); //true
isFunction(Symbol); //true
isFunction({}); //false
isFunction([]); //false
isFunction("function"); //false
isFunction(true); //false
isFunction(1); //false
isFunction("Alireza Dezfoolian"); //false
答案 11 :(得分:5)
如果您使用Lodash,则可以使用_.isFunction。
_.isFunction(function(){});
// => true
_.isFunction(/abc/);
// => false
_.isFunction(true);
// => false
_.isFunction(null);
// => false
如果value是函数,则此方法返回true
,否则返回false
。
答案 12 :(得分:4)
以下似乎对我也有用(从node.js
测试):
var isFunction = function(o) {
return Function.prototype.isPrototypeOf(o);
};
console.log(isFunction(function(){})); // true
console.log(isFunction({})); // false
答案 13 :(得分:4)
我发现在IE8中测试本机浏览器功能时,使用toString
,instanceof
和typeof
不起作用。这是一个在IE8中工作正常的方法(据我所知):
function isFn(f){
return !!(f && f.call && f.apply);
}
//Returns true in IE7/8
isFn(document.getElementById);
或者,您可以使用以下方法检查本机功能:
"getElementById" in document
尽管如此,我已经在某处读过,这在IE7及以下版本中并不总是有效。
答案 14 :(得分:3)
从节点v0.11开始,您可以使用标准的util函数:
var util = require('util');
util.isFunction('foo');
答案 15 :(得分:3)
我认为您可以在Function原型上定义一个标志,并检查您要测试的实例是否继承了
定义一个标志:
Function.prototype.isFunction = true;
,然后检查是否存在
var foo = function(){};
foo.isFunction; // will return true
缺点是另一个原型可以定义相同的标志然后它没有价值,但如果您完全控制所包含的模块,那么这是最简单的方法
答案 16 :(得分:1)
您应该在js。
中使用typeOf
运算符
var a=function(){
alert("fun a");
}
alert(typeof a);// alerts "function"
答案 17 :(得分:0)
以前的答案显示的解决方案是使用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]();
}
答案 18 :(得分:0)
注意这一点:
typeof Object === "function" // true.