在 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 解决了这些问题:
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 在这种情况下使用 IF 或 SWITCH 或“动态函数名”的最佳实践是啥