在 JavaScript 中测试函数的最佳方法是啥?

Posted

技术标签:

【中文标题】在 JavaScript 中测试函数的最佳方法是啥?【英文标题】:Best method of testing for a function in JavaScript?在 JavaScript 中测试函数的最佳方法是什么? 【发布时间】:2010-09-29 03:25:44 【问题描述】:

我对此进行了大量研究,但似乎使用的方法不一致且多种多样。

以下是我过去使用过的一些方法:

/* 1: */  typeof myFunc === 'function'
/* 2: */  myFunc.constructor === Function
/* 3: */  myFunc instanceof Function

作为我研究的一部分,我了解了一些知名图书馆是如何做到这一点的:

 /* jQuery 1.2.6: */  !!fn && typeof fn != "string" && !fn.nodeName && fn.constructor != Array && /^[\s[]?function/.test( fn + "" )
 /* jQuery 1.3b1: */  toString.call(obj) === "[object Function]"
/* Prototype 1.6: */  typeof object == "function"
      /* YUI 2.6: */  typeof o === 'function'

我很惊讶有这么多不同的方法被使用,肯定已经同意了一个可接受的测试吗?而且我完全不知道 jQuery 1.2.6 的再现的意图是什么,看起来有点 OTT...

那么,我的问题仍然存在,测试函数的最佳*方法是什么?

我也希望能深入了解上述一些方法,尤其是 jQuery 1.2.6 的方法。 (我可以看到他们在做什么,只是看起来很奇怪)

[*] 我所说的“最佳”是指最广泛接受的跨浏览器兼容方法。


编辑:是的,我知道它之前已经讨论过,但我仍然想讨论一下最有效的方法。为什么有这么多不同的使用方法?

到目前为止,关于 SO 的讨论只提到了 typeof 运算符(大部分),但没有人暗示替代方法的有效性。

【问题讨论】:

【参考方案1】:

测试对象是否为函数的最佳方法是typeof myFunc === 'function'。如果您正在使用库,请使用该库的功能测试:jQuery.isFunction(myFunc)

使用typeof 时,可能被误报为函数。这是非常罕见的,但有一个库可以消除这些不一致。 jQuery 解决了这些问题:

Firefox 使用typeof document.createElement("object") 报告功能 Safari 报告功能与typeof document.body.childNodes 旧版本的 Firefox 将正则表达式报告为函数(在 3.0 中不是这种情况)。 一些 IE 内置的全局函数 (alert) 和一些节点方法 (getAttribute) 被报告为“对象”类型。

使用instanceof 而不是typeof 可以绕过其中的一些。例如,document.createElement("object") instanceof Function 在 Firefox 中是 false

您可以在the original ticket (#3618) 的 cmets 中查看第一个方法的诞生。新方法来自changeset 5947,似乎是 Resig 为解决IE memory leaks 而发明的。它可能更慢,但更小,更干净。

这里的 == 和 === 在工作方式方面没有太大区别,但严格的评估稍微快一点,因此更受欢迎。

【讨论】:

感谢博格的解释! :)【参考方案2】:

jQuery 的开发者 John Resig 似乎确实在 jQuery 的内部做出了一些奇怪的选择。

toString.call(obj) === "[object Function]"

看起来很整洁,但我想不出任何情况,如果简单的typeof 方法会失败,但我想不出上面的任何情况,但也许他知道其他使用方法不知道的东西。

typeof o === "function"

我会选择后者,因为它更清晰,除非你有强有力的证据表明它不起作用。

【讨论】:

当你问一个函数是否是一个函数时,IE 中有一些情况......并且 IE 说它是一个对象(不记得确切的场景)我猜 Resig 在这里的选择可能成为 IE 错误的解决方法。【参考方案3】:

为什么在typeof 上使用严格相等,因为两个操作数都是字符串?我忽略了一些问题?

无论如何,我会采用更简单的 typeof 方式,这似乎是为此而做的并且是可读的。 instanceof 也是可读的,但它似乎更强调函数是一个对象这一事实,这可能与问题无关。

【讨论】:

我认为严格的平等只是严格遵守而不是技术上的合理......

以上是关于在 JavaScript 中测试函数的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 组件中放置 JavaScript 监听函数的最佳位置是啥?

打破 JavaScript 中嵌套循环的最佳方法是啥?

Javascript 在这种情况下使用 IF 或 SWITCH 或“动态函数名”的最佳实践是啥

在 Javascript 中进行浏览器检测的最佳方法是啥?

在 Javascript 中验证响应来自我的服务器的最佳方法是啥?

在javascript中用逗号格式化数字变量的最佳方法是啥