Javascript 判断函数类型完美解决方案


Posted in Javascript onSeptember 02, 2009

但是,有一些细节并不为我们所熟知。John Resig 在分析了这些细节之后,为我们提供了一个完美的解决方案,本文将作详细介绍:

一、传统方法不为人所知的细节
毫无疑问,在判断函数类型时,我们使用的是typeof方法,比如:

function fn(){ 
//content 
} 
alert(typeof fn)//结果是"function"。

但是,该方法在一些浏览器中并不是像我们想像的那样工作。

1、Firefox2和Firefox3
在这两个浏览器中,用typeof检测HTML对象元素的类型,得到是一个不精确的“function”结果,而不是“object”,如HTMLDocument。如:

alert(typeof HTMLDocument); 
//在Firefox2中结果是"function"; 
//在Firefox3中结果是"object";

2、Firefox2
对于正则表达式,在该浏览器中返回的结果是“function”(在Firefox3中结果是“object”),如:
var reg = /test/; 
alert(typeof reg); 
//在Firefox2中结果是"function"; 
//在Firefox3中结果是"object";

注:本人在safari中测试,其结果也是“function”。
3、IE6和IE7
在IE中对DOM元素使用typeof方法,得到的结果是“object”。如:
alert(typeof document.getElementsByTagName("body")[0].getAttribute); 
//结果是"object"

4、Safari 3
safari认为DOM元素的NodeList是一个函数,如:
alert(typeof document.body.childNodes); 
//结果是"function"

很明显,如果你要测试一个对象是否为函数,使用typeof方法并不能从真正意义上保证测试结果。那么,我们就需要一种在所有浏览器中都能保证测试结果的解决方案。我们知道function本身有apply()和call()两种方法,但这两个方法在IE中存在问题的函数中并不存在,试试下面的测试:
alert(typeof document.getElementsByTagName("body")[0].getAttribute.call) 
//在IE中结果是"undefined"

显然,我们不能利用这两个方法。

二、完美解决方案及实现过程
John Resig为我们提供了一个完美的解决方案,这个复杂但很稳定的判断一个对象是否为函数的方法如下:

function isFunction( fn ) { 
return !!fn && !fn.nodeName && fn.constructor != String && 
fn.constructor != RegExp && fn.constructor != Array && 
/function/i.test( fn + "" ); 
}

这个函数首先保证测试的对象存在,并将其序列化成含有“function”的字符串,这个是我们检测的基础(fn.constructor != String,fn.constructor != Array, and fn.constructor != RegExp)。另外,我们需要保证声明的函数不是一个DOM节点(fn.nodeName)。然后,我们就可以作toString测试。如果我们将一个函数转换成字符串,在一个浏览器中(fn+"")给我们的结果就像这样“function name(){...}”。现在,判断它是否为函数就很简单,仅仅只需要判断字符串中是否包含单词“function”。这很神奇,对于任何有问题的函数,在所有浏览器中都能得到我们所需要的结果。这个函数较之于传统的方法,运行速度有些不尽人意,作者建议我们保守使用。

John Resig 是jQuery库的开发者,相信使用该库的朋友们对该库简洁的语法和优秀的性能并不陌生。作者除追求代码简洁和性能高效之外,其尽善尽美的精神也让人叹服。如果你是一个完美主义者,相信此文对你很有帮助。

Javascript 相关文章推荐
js实现简单模态窗口,背景灰显
Nov 14 Javascript
js正确获取元素样式详解
Aug 07 Javascript
深入理解JavaScript系列(50):Function模式(下篇)
Mar 04 Javascript
基于jquery实现简单的手风琴特效
Nov 24 Javascript
轻松实现javascript图片轮播特效
Jan 13 Javascript
通过js修改input、select默认字体颜色
Apr 19 Javascript
javaScript手机号码校验工具类PhoneUtils详解
Dec 08 Javascript
vue vuex vue-rouert后台项目——权限路由(适合初学)
Dec 29 Javascript
vue cli4下环境变量和模式示例详解
Apr 09 Javascript
微信小程序自定义联系人弹窗
May 26 Javascript
JS如何判断对象是否包含某个属性
Aug 29 Javascript
原生js实现弹窗消息动画
Nov 20 Javascript
javascript 控制 html元素 显示/隐藏实现代码
Sep 01 #Javascript
jsTree树控件(基于jQuery, 超强悍)[推荐]
Sep 01 #Javascript
JavaScript 继承详解 第一篇
Aug 30 #Javascript
JavaScript 应用技巧集合[推荐]
Aug 30 #Javascript
用cssText批量修改样式
Aug 29 #Javascript
javascript appendChild,innerHTML,join性能比较代码
Aug 29 #Javascript
IE 条件注释详解总结(附实例代码)
Aug 29 #Javascript
You might like
初学者入门:细述PHP4的核心Zend
2006/09/05 PHP
第九节--绑定
2006/11/16 PHP
PHP与SQL注入攻击[三]
2007/04/17 PHP
php使用百度天气接口示例
2014/04/22 PHP
PHP版本如何选择?应该使用哪个版本?
2015/05/13 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
PHP封装的分页类与简单用法示例
2019/02/25 PHP
JavaScript CSS菜单功能 改进版
2008/12/20 Javascript
javascript倒计时功能实现代码
2012/06/07 Javascript
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
javascript中innerText和innerHTML属性用法实例分析
2015/05/13 Javascript
JavaScript中的Repaint和Reflow用法详解
2015/07/27 Javascript
AngularJS 实现按需异步加载实例代码
2015/10/18 Javascript
javascript每日必学之基础入门
2016/02/16 Javascript
使用struts2+Ajax+jquery验证用户名是否已被注册
2016/03/22 Javascript
[原创]Javascript 实现广告后加载 可加载百度谷歌联盟广告
2016/05/11 Javascript
js点击按钮实现水波纹效果代码(CSS3和Canves)
2016/09/15 Javascript
基于JavaScript实现窗口拖动效果
2017/01/18 Javascript
nodeJs链接Mysql做增删改查的简单操作
2017/02/04 NodeJs
node.JS md5加密中文与php结果不一致的解决方法
2017/05/05 Javascript
详解tween.js 中文使用指南
2018/01/05 Javascript
JS实现简单随机3D骰子
2019/10/24 Javascript
Vue优化:常见会导致内存泄漏问题及优化详解
2020/08/04 Javascript
python中类变量与成员变量的使用注意点总结
2017/04/29 Python
Python使用遗传算法解决最大流问题
2018/01/29 Python
Pandas 数据处理,数据清洗详解
2018/07/10 Python
Python中调用其他程序的方式详解
2019/08/06 Python
python中random.randint和random.randrange的区别详解
2020/09/20 Python
解决python 在for循环并且pop数组的时候会跳过某些元素的问题
2020/12/11 Python
Python如何实现单例模式
2016/06/03 面试题
法学专业自我鉴定
2014/02/05 职场文书
企业总经理助理岗位职责
2014/09/12 职场文书
2014年底个人工作总结
2015/03/10 职场文书
2015年秋季运动会广播稿
2015/08/19 职场文书
Golang 正则匹配效率详解
2021/04/25 Golang
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js