当前位置:编程学习 > JS >>

Javascript函数类型的判断

在判断函数类型时,我们使用的是typeof方法,比如:

  1. function fn(){  
  2. //content  
  3. }  
  4. alert(typeof fn)//结果是"function"。 

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

1、Firefox2和Firefox3

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

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

2、Firefox2

对于正则表达式,在该浏览器中返回的结果是“function”(在Firefox3中结果是“object”),如:

  1. var reg = /test/;  
  2. alert(typeof reg);  
  3. //在Firefox2中结果是"function";  
  4. //在Firefox3中结果是"object"; 

注:本人在safari中测试,其结果也是“function”。

3、IE6和IE7

在IE中对DOM元素使用typeof方法,得到的结果是“object”。如:

  1. alert(typeof document.getElementsByTagName("body")[0].getAttribute);  
  2. //结果是"object" 

4、Safari 3

safari认为DOM元素的NodeList是一个函数,如:

  1. alert(typeof document.body.childNodes);  
  2. //结果是"function" 

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

  1. alert(typeof  document.getElementsByTagName("body")[0].getAttribute.call)  
  2. //在IE中结果是"undefined" 

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

二、完美解决方案及实现过程

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

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

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

补充:网页制作,js教程 
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,