假设有任意变量,定义如下:
var a = function() {/* Statements */};
我想要一个函数来检查变量的类型是否为类函数。例如:
function foo(v) {if (v is function type?) {/* do something */}};
foo(a);
我怎样才能检查变量a是否为上述定义的函数类型?
假设有任意变量,定义如下:
var a = function() {/* Statements */};
我想要一个函数来检查变量的类型是否为类函数。例如:
function foo(v) {if (v is function type?) {/* do something */}};
foo(a);
我怎样才能检查变量a是否为上述定义的函数类型?
当前回答
@grandecomplex:你的解决方案相当冗长。如果这样写会更清楚:
function isFunction(x) {
return Object.prototype.toString.call(x) == '[object Function]';
}
其他回答
if (typeof v === 'function') {
// do something
}
我认为你可以在Function原型上定义一个标志,然后检查你想测试的实例是否继承了这个标志
定义一个标志:
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。
从节点v0.11开始,你可以使用标准的util函数:
var util = require('util');
util.isFunction('foo');
对于那些对函数式风格感兴趣,或者在元编程中寻找更有表现力的方法(如类型检查)的人来说,看到Ramda库来完成这样的任务可能会很有趣。
下面的代码只包含纯函数和无点函数:
const R = require('ramda');
const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
const equalsSyncFunction = isPrototypeEquals(() => {});
const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
从ES2017开始,异步函数是可用的,所以我们也可以检查它们:
const equalsAsyncFunction = isPrototypeEquals(async () => {});
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
然后把它们组合在一起:
const isFunction = R.either(isSyncFunction, isAsyncFunction);
当然,函数应该被保护不受空值和未定义值的影响,所以为了使它“安全”:
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 ));
但是,请注意,由于大量使用高阶函数,此解决方案的性能可能低于其他可用选项。