检查一个变量是否为函数类型

1234

假设我有一个变量,其定义如下:

var a = function() {/* Statements */};

我希望有一个函数可以检查变量的类型是否类似于函数。例如:

function foo(v) {if (v is function type?) {/* do something */}};
foo(a);

我如何检查变量 a 是否为上述定义的 Function 类型?


3
这里是一个基准,用于检查最常见的方法:http://jsben.ch/#/e5Ogr - EscapeNetscape
一个内省方法,比如isES3Function,可以检测传入的value是否是在ES3中独有的函数类型,而isGenericFunction则可以检测传入的value是否是一个通用的(或者说不具体/非具体)函数,因此可以是一个传统的ES3函数或者一个非异步箭头函数。 - undefined
如今,功能特定的内省比人们首先想象的要复杂得多。一些情况可以直接解决。无法检测到的情况必须从配置中查找。大多数情况可以通过结合两种方法来推断,应用包括和排除策略。例如,检测一个良好的旧的ES3函数的方式是...它是一个函数类型,具有可写的原型,既不是生成器也不是类。 - undefined
22个回答

0

请注意:

这个。
typeof Object === "function" // true.
typeof Array  === "function" // true

1
ObjectArray都是构造函数,尽管它们共享一些静态方法,你可能想要使用,但几乎没有人会像那样检查它们的类型。有什么原因会发生这种情况吗?目前我想不出除了程序员错误之外的任何原因。 - Shape

0
这是一个有点棘手的问题,因为你需要先定义“什么是函数?”。 让我们来看看Node(JavaScript引擎的V8实现)。它是用C++编写的,但也有一部分是用JavaScript编写的。 一些函数被神奇地映射到C++函数。它们不具备标准函数的所有属性。 其他函数只是原型设置为null的JavaScript函数。这意味着它们不继承自Object,也没有像toString()等方法。 然后最后你有标准的Function实例。 还有AsyncFunction,它是一个Function,但有些不同。 想想一个返回函数的Promise - 它是一个Function还是一个Promise?Promise是一个Function吗?
这里我们来看一下Node如何实现检查参数是否为AsyncFunction: readable-stream 将AsyncFunction定义为async函数的原型。 然后类型检查就是简单的 typeof arg === 'function',可以在这里看到。
  • 首先,你需要定义“什么是函数”
  • 如果你将其理解为某个类的实例,那么你可以使用例如 arg instanceof Function,它会返回一个布尔值
  • 如果你想查看函数继承自哪里,那么你可以检查它的原型
  • 如果你定义了任何可以被称为函数的东西,那么就检查它是否可调用
  • 但是仍然存在一些问题 :(
// It doesn't really matter if you use named function or not - but that is cool to know that it can have a name :)
let f = function aNamedFunction(){console.log('hello')};
f.prototype = null;
console.log(f instanceof Function, typeof f); // true, function
f.__proto__ = null;
console.log(f instanceof Function); // false, function
console.log(Object.getOwnPropertyNames(f)); // prototype, length, name
f(); // 'hello'


总结一下: typeof arg === 'function' 看起来很不错(尽管有一些特殊情况可能会失败)。

功能特定的内省 比你上面提到的更加复杂。只有少数情况可以直接解决。那些无法检测到的情况必须从配置中查找。大多数情况可以通过结合两种方法,应用包括/排除策略来推断出来。例如,检测一个好的旧的ES3函数 就是这样的... 是一个函数类型,具有可写的原型,既不是生成器也不是类。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接