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 相关文章推荐
你需要知道的JavsScript可以做什么?
Jun 29 Javascript
JavaScript 原型继承之构造函数继承
Aug 26 Javascript
jquery多行滚动/向左或向上滚动/响应鼠标实现思路及代码
Jan 23 Javascript
Javascript简单实现面向对象编程继承实例代码
Nov 27 Javascript
用canvas 实现个图片三角化(LOW POLY)效果
Feb 18 Javascript
jQuery获取当前点击的对象元素(实现代码)
May 19 Javascript
jQueryUI 拖放排序遇到滚动条时有可能无法执行排序的小bug及解决方案
Dec 19 Javascript
原生js实现日期计算器功能
Feb 17 Javascript
vue+canvas实现拼图小游戏
Sep 18 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
Nov 17 Javascript
JS实现京东商品分类侧边栏
Dec 11 Javascript
node中使用shell脚本的方法步骤
Mar 23 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
PHP中PDO基础教程 入门级
2011/09/04 PHP
解析PHP跨站刷票的实现代码
2013/06/18 PHP
用php和jQuery来实现“顶”和“踩”的投票功能
2016/10/13 PHP
php表单习惯用的正则表达式
2017/10/11 PHP
比较搞笑的js陷阱题
2010/02/07 Javascript
Javascript 类与静态类的实现
2010/04/01 Javascript
js修改table中Td的值(定义td的单击事件)
2013/01/10 Javascript
jQuery回车实现登录简单实现
2013/08/20 Javascript
jQuery+ajax实现鼠标单击修改内容的方法
2014/06/27 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
使用jQuery的easydrag插件实现可拖动的DIV弹出框
2016/02/19 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
微信小程序 石头剪刀布实例代码
2017/01/04 Javascript
jquery精度计算代码 jquery指定精确小数位
2017/02/06 Javascript
canvas实现爱心和彩虹雨效果
2017/03/09 Javascript
vue 如何添加全局函数或全局变量以及单页面的title设置总结
2017/06/01 Javascript
ionic App问题总结系列之ionic点击系统返回键退出App
2017/08/19 Javascript
JavaScript实现微信红包算法及问题解决方法
2018/04/26 Javascript
详解JavaScript 中 if / if...else...替换方式
2018/07/15 Javascript
基于jQuery的时间戳与日期间的转化
2019/06/21 jQuery
python在windows下创建隐藏窗口子进程的方法
2015/06/04 Python
Python程序中设置HTTP代理
2016/11/06 Python
Python面向对象之类的定义与继承用法示例
2019/01/14 Python
详解Python 定时框架 Apscheduler原理及安装过程
2019/06/14 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
2020/01/04 Python
Pytorch转onnx、torchscript方式
2020/05/25 Python
Python常用类型转换实现代码实例
2020/07/28 Python
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
西班牙香水和化妆品连锁店:Druni
2019/05/05 全球购物
《学棋》教后反思
2014/04/14 职场文书
出售房屋协议书范本
2014/10/06 职场文书
2014年小学图书室工作总结
2014/12/09 职场文书
小学运动会报道稿
2015/07/22 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
倡议书怎么写?
2019/04/11 职场文书
MySQL对数据表已有表进行分区表的实现
2021/11/01 MySQL