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 相关文章推荐
仅IE9/10同时支持script元素的onload和onreadystatechange事件分析
Apr 27 Javascript
javascript的函数作用域
Nov 12 Javascript
js限制input标签中只能输入中文
Jun 26 Javascript
jquery实现鼠标滑过小图查看大图的方法
Jul 20 Javascript
AngularJS之依赖注入模拟实现
Aug 19 Javascript
Bootstrapvalidator校验、校验清除重置的实现代码(推荐)
Sep 28 Javascript
Vue.js bootstrap前端实现分页和排序
Mar 10 Javascript
详解Vue单元测试Karma+Mocha学习笔记
Jan 31 Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
Jan 18 Javascript
vue3.0中的双向数据绑定方法及优缺点
Aug 01 Javascript
uniapp电商小程序实现订单30分钟倒计时
Nov 01 Javascript
Vue用mixin合并重复代码的实现
Nov 27 Vue.js
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之Smarty入门
2007/01/04 PHP
用PHP生成html分页列表的代码
2007/03/18 PHP
php数据库的增删改查 php与javascript之间的交互
2017/08/31 PHP
Laravel Validator自定义错误返回提示消息并在前端展示
2019/05/09 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
2020/08/07 PHP
Chrome Form多次提交表单问题的解决方法
2011/05/09 Javascript
JS实现仿百度输入框自动匹配功能的示例代码
2014/02/19 Javascript
jquery 实现两Select 标签项互调示例代码
2014/09/25 Javascript
使用JS实现jQuery的addClass, removeClass, hasClass函数功能
2014/10/31 Javascript
jquery拖拽排序简单实现方法(效果增强版)
2016/02/16 Javascript
Bootstrap的基本应用要点浅析
2016/12/19 Javascript
从零学习node.js之模块规范(一)
2017/02/21 Javascript
JavaScript中 this 指向问题深度解析
2017/02/21 Javascript
js实现简单的获取验证码按钮效果
2017/03/03 Javascript
javascript获取指定区间范围随机数的方法
2017/09/08 Javascript
iphone刘海屏页面适配方法
2019/05/07 Javascript
有关vue 开发钉钉 H5 微应用 dd.ready() 不执行问题及快速解决方案
2020/05/09 Javascript
解决VUE-Router 同一页面第二次进入不刷新的问题
2020/07/22 Javascript
python套接字流重定向实例汇总
2016/03/03 Python
Python中操作符重载用法分析
2016/04/29 Python
使用Python脚本和ADB命令实现卸载App
2017/02/10 Python
python解释器pycharm安装及环境变量配置教程图文详解
2020/02/26 Python
Python3爬虫中Ajax的用法
2020/07/10 Python
利用SVG和CSS3来实现一个炫酷的边框动画
2015/07/22 HTML / CSS
HTML5中外部浏览器唤起微信分享
2020/01/02 HTML / CSS
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
管理专员自荐信
2014/01/26 职场文书
元旦晚会主持词
2014/03/24 职场文书
在职党员进社区活动总结
2014/07/05 职场文书
护士年终考核评语
2014/12/31 职场文书
奖励申请报告范文
2015/05/15 职场文书
2019军训心得体会
2019/06/27 职场文书
python 如何在list中找Topk的数值和索引
2021/05/20 Python
漫画「狩龙人拉格纳」公开TV动画预告图
2022/03/22 日漫
vue实现列表拖拽排序的示例代码
2022/04/08 Vue.js