jQuery中isFunction方法的BUG修复

jQuery 1.4 源码 449 行(core.js 431 行),判断是否为函数的方法如下(思路来源于 Douglas Crockford 的《The Miller Device》):

isFunction: function( obj ) {
    return toString.call(obj) === "[object Function]";
},

同时 jQuery 的作者也作了部分注释:

See test/unit/core.js for details concerning isFunction. Since version 1.3, DOM methods and functions like alert aren't supported. They return false on IE (#2968).

即:此方法在 IE 下无法正确识别 DOM 方法和一些函数(例如 alert 方法等)。

为什么会这样呢?

修复 jQuery 中 isFunction 方法的 BUG

使用 typeof 运算符检测各种方法:

document.writeln('typeof eval: ' + typeof eval + '
');
document.writeln('typeof confirm: ' + typeof confirm + '
');
document.writeln('typeof confirm: ' + typeof window.open + '
');
document.writeln('typeof alert: ' + typeof alert + '
');
document.writeln('typeof window.alert: ' + typeof window.alert + '
');
document.writeln('typeof document.getElementById: ' + typeof document.getElementById + '
');
document.writeln('typeof document.createElement: ' + typeof document.createElement + '
');

测试原始的 isFunction 函数方法

var isFunction = function( fn, name ) {
return document.writeln('isFunction(' + name + '): ' + (Object.prototype.toString.call(fn) === "[object Function]") + '
');

}

isFunction(eval,'eval');
isFunction(confirm, 'confirm');
isFunction(window.open, 'window.open');
isFunction(alert, 'alert');
isFunction(window.alert, 'window.alert');
isFunction(document.getElementById, 'document.getElementById');
isFunction(document.createElement, 'document.createElement');
isFunction(isFunction, 'isFunction');

测试修复后 isFunction 函数方法

var isFunction = (function() {
return typeof document.getElementById === "object" ?
isFunction = function(fn, name){
try {
return document.writeln('isFunction(' + name + '): ' + (/^\s*\bfunction\b/.test("" + fn)) + '
');
} catch (x) {
return document.writeln('isFunction(' + name + '): ' + (false) + '
');
}
}:
isFunction = function(fn, name){
return document.writeln('isFunction(' + name + '): ' + ("[object Function]" === Object.prototype.toString.call(fn)) + '
');
};
})()

isFunction(eval,'eval');
isFunction(confirm, 'confirm');
isFunction(window.open, 'window.open');
isFunction(alert, 'alert');
isFunction(window.alert, 'window.alert');
isFunction(document.getElementById, 'document.getElementById');
isFunction(document.createElement, 'document.createElement');
isFunction(isFunction, 'isFunction');

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

会发现在 IE 下用 typeof 检测 alert、confirm 方法以及 DOM 的方法显示 object,而其他浏览器下显示 function。

那如何完善这个问题呢?

  1. typeof 检测某个方法(例如:document.getElementById) 是否是 object,如何是,则重写 isFunction 函数;
  2. 怎样重写呢?正则判断传入的对象字符串后(”" + fn),是否起始位置含有 function,即:/^\s*\bfunction\b/.test(” + fn)。

OK,看下根据以上思路修改后的 isFunction 函数:


代码如下:

var isFunction = (function() { // Performance optimization: Lazy Function Definition return "object" === typeof document.getElementById ? isFunction = function(fn){ try { return /^\s*\bfunction\b/.test("" + fn); } catch (x) { return false } }: isFunction = function(fn){ return "[object Function]" === Object.prototype.toString.call(fn); };})()

参考阅读:


AKPC_IDS += "376,";

(0)

相关推荐

  • isArray()函数(JavaScript中对象类型判断的几种方法)

    1) typeof 运算符 typeof 是一元运算符,返回结果是一个说明运算数类型的字符串.如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在). 但 typeof 的能力有限,其对于Date.RegExp类型返回的都是"object".如: typeof {}; //

  • 代码分析jQuery四种静态方法使用

    jQery每一个方法都有对应代码解析,非常详细,具有介绍请看下文: isFunction方法 用于测试是否为函数的对象 示例: function stub() { } var objs = [ function () {}, { x:15, y:20 }, null, stub, "function" ]; jQuery.each(objs, function (i) { var isFunc = jQuery.isFunction(objs[i]); $("span:eq(

  • js判断是否为数组的函数: isArray()

    今天刚好在学习支付宝 JS 框架 base.js .瞄了一下,实现是这样的: 复制代码 代码如下: if (value instanceof Array || (!(value instanceof Object) && (Object.prototype.toString.call((value)) == '[object Array]') || typeof value.length == 'number' && typeof value.splice != 'unde

  • JavaScript isArray()函数判断对象类型的种种方法

    1) typeof 运算符 typeof 是一元运算符,返回结果是一个说明运算数类型的字符串.如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在). 但 typeof 的能力有限,其对于Date.RegExp类型返回的都是"object".如: 复制代码 代码如下: typ

  • 关于jQuery $.isNumeric vs. $.isNaN vs. isNaN

    在jQuery中,有几种方式可以判断一个对象是否是数字,或者可否转换为数字.首先,jQuery.isNaN()在最新版本中已经被移除了(1.7之后),取而代之的是  jQuery.isNumeric ().这并不奇怪,因为jQuery.isNaN() 同Javascript内置的isNaN()名字相同,但是语义却不完全相同,在一定意义上会造成歧义. jQuery.isNumeric ()有着与其相似的功能,同时也解决了歧义问题. jQuery.isNumeric ()检查传进的参数是否是数字或者

  • jQuery中isFunction方法的BUG修复

    jQuery 1.4 源码 449 行(core.js 431 行),判断是否为函数的方法如下(思路来源于 Douglas Crockford 的<The Miller Device>): isFunction: function( obj ) {    return toString.call(obj) === "[object Function]";}, 同时 jQuery 的作者也作了部分注释: See test/unit/core.js for details co

  • jQuery中prevAll()方法用法实例

    本文实例讲述了jQuery中prevAll()方法用法.分享给大家供大家参考.具体分析如下: 此方法查找匹配元素集合之前所有的同辈元素. 同辈元素集合可以通过选择器进行筛选. 语法结构: 复制代码 代码如下: $("selector").prevAll(expr) 参数列表: 参数 描述 expr 可选.用于过滤的表达式. 实例代码: 实例一: 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta cha

  • jquery中post方法用法实例

    本文实例讲述了jquery中post方法的用法,分享给大家供大家参考.具体用法分析如下: 在使用jquery实现网站的异步交互时,常用的两个函数为get和post方法,get方法使用很简单,直接提交get请求即可,如果有参数,直接追加到url后面就行,但是使用post方法时,传递参数,需要和url分开写,使得传参变得麻烦了,不过这样做起来更安全一些,而且出现中文乱码的概率也要低一些(get方法传中文很多情况下会出现乱码现象),这里就详细介绍一下post是怎样传递参数的. 首先写一个html代码如

  • jQuery中get方法用法分析

    本文实例讲述了jQuery中get方法用法.分享给大家供大家参考,具体如下: 参数:url,[data],[callback],[type] url 待载入页面的URL地址. data 待发送 Key/value 参数. callback 载入成功时回调函数. type 返回内容格式,xml, html, script, json, text, _default. 案例1 表单代码: <form id="form1" action="#"> <p&

  • jQuery中innerHeight()方法用法实例

    本文实例讲述了jQuery中innerHeight()方法用法.分享给大家供大家参考.具体分析如下: 获取第一个匹配元素内部区域高度. 包括内补白(padding).不包括边框border). 也就是说内部区域的宽度等于width和padding之和. 此方法对可见和隐藏元素均有效. 可以结合innerWidth()方法学习. 语法结构: 复制代码 代码如下: $(selector).innerHeight() 实例代码: 复制代码 代码如下: <!DOCTYPE html> <html

  • jQuery中die()方法用法实例

    本文实例讲述了jQuery中die()方法用法.分享给大家供大家参考.具体分析如下: 此方法移除所有通过live()方法向指定元素添加的一个或多个事件处理程序. 语法结构: 复制代码 代码如下: $(selector).die(type,function) 参数列表: 参数 描述 type 可选.定义附加到元素的一个或多个事件类型.由空格分隔多个事件值. function 定义当事件发生时运行的函数. 实例代码: 复制代码 代码如下: <!DOCTYPE html> <html>

  • jQuery中data()方法用法实例

    本文实例讲述了jQuery中data()方法用法.分享给大家供大家参考.具体分析如下: 此方法可以向匹配元素附加数据,或者从匹配元素获取数据. 语法结构一: 复制代码 代码如下: $(selector).data(name,value) 参数列表: 参数 描述 name 存储的数据名称. value 将要存储的任意数据. 实例代码: 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-

  • jquery中load方法的用法及注意事项说明

    调用load方法的完整格式是:load( url, [data], [callback] ),其中 url:是指要导入文件的地址. data:可选参数:因为Load不仅仅可以导入静态的html文件,还可以导入动态脚本,例如PHP文件,所以要导入的是动态文件时,我们可以把要传递的参数放在这里. callback:可选参数:是指调用load方法并得到服务器响应后,再执行的另外一个函数. 一:如何使用data 1.加载一个php文件,该php文件不含传递参数 $("#myID").load(

  • jQuery中scrollLeft()方法用法实例

    本文实例讲述了jQuery中scrollLeft()方法用法.分享给大家供大家参考.具体分析如下: 此方法获取或设置匹配元素相对滚动条左侧的偏移(offset)量. 语法结构一: 当scrollLeft()方法没有参数的时候就是获取匹配元素相对滚动条左侧的偏移量. 复制代码 代码如下: $(selector).scrollLeft() 实例代码: 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset=&quo

  • jQuery中each()方法用法实例

    本文实例讲述了jQuery中each()方法用法.分享给大家供大家参考.具体分析如下: 此方法可以以匹配元素集合中每一个元素作为上下文去执行一个函数. 当每次执行函数时,函数的执行环境都是一个匹配元素集合中不同的DOM元素,并且会将此元素在集合中索引传递给此函数,索引值是从0开始的.通过返回false可用于提早停止循环运行,返回true将继续执行函数,直到匹配元素中每一个元素都遍历完成. each()方法不同于jQuery.each()方法 .each()方法只能够遍历JQuery对象,而jQu

随机推荐