jQuery中isFunction方法的BUG修复
作者:bea
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 conc
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 方法等)。
为什么会这样呢?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>修复 jQuery 中 isFunction 方法的 BUG</title>
</head>
<body>
<h3>使用 typeof 运算符检测各种方法:</h3>
<script>
document.writeln('typeof eval: ' + typeof eval + '<br>');
document.writeln('typeof confirm: ' + typeof confirm + '<br>');
document.writeln('typeof confirm: ' + typeof window.open + '<br>');
document.writeln('typeof alert: ' + typeof alert + '<br>');
document.writeln('typeof window.alert: ' + typeof window.alert + '<br>');
document.writeln('typeof document.getElementById: ' + typeof document.getElementById + '<br>');
document.writeln('typeof document.createElement: ' + typeof document.createElement + '<br>');
</script>
<h3>测试原始的 isFunction 函数方法</h3>
<script>
var isFunction = function( fn, name ) {
return document.writeln('isFunction(' + name + '): ' + (Object.prototype.toString.call(fn) === "[object Function]") + '<br>');
}
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');
</script>
<h3>测试修复后 isFunction 函数方法</h3>
<script>
var isFunction = (function() {
return typeof document.getElementById === "object" ?
isFunction = function(fn, name){
try {
return document.writeln('isFunction(' + name + '): ' + (/^s*function/.test("" + fn)) + '<br>');
} catch (x) {
return document.writeln('isFunction(' + name + '): ' + (false) + '<br>');
}
}:
isFunction = function(fn, name){
return document.writeln('isFunction(' + name + '): ' + ("[object Function]" === Object.prototype.toString.call(fn)) + '<br>');
};
})()
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');
</script>
</body>
</html>
[Ctrl+A 全选 注:
如需引入外部Js需刷新才能执行]
会发现在 IE 下用 typeof 检测 alert、confirm 方法以及 DOM 的方法显示 object,而其他浏览器下显示 function。
那如何完善这个问题呢?
typeof 检测某个方法(例如:document.getElementById) 是否是 object,如何是,则重写 isFunction 函数;
怎样重写呢?正则判断传入的对象字符串后(”" + fn),是否起始位置含有 function,即:/^s*function/.test(” + fn)。
OK,看下根据以上思路修改后的 isFunction 函数:
代码如下:
var isFunction = (function() { // Performance optimization: Lazy Function Definition return "object" === typeof document.getElementById ? isFunction = function(fn){ try { return /^s*function/.test("" + fn); } catch (x) { return false } }: isFunction = function(fn){ return "[object Function]" === Object.prototype.toString.call(fn); };})()
参考阅读:
《isFunction hacked, isCallable solution》
《isFunction() or isObject(), that is the question ? 》
《Lazy Function Definition Pattern》
AKPC_IDS += "376,";
有用 | 无用
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 方法等)。
为什么会这样呢?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>修复 jQuery 中 isFunction 方法的 BUG</title>
</head>
<body>
<h3>使用 typeof 运算符检测各种方法:</h3>
<script>
document.writeln('typeof eval: ' + typeof eval + '<br>');
document.writeln('typeof confirm: ' + typeof confirm + '<br>');
document.writeln('typeof confirm: ' + typeof window.open + '<br>');
document.writeln('typeof alert: ' + typeof alert + '<br>');
document.writeln('typeof window.alert: ' + typeof window.alert + '<br>');
document.writeln('typeof document.getElementById: ' + typeof document.getElementById + '<br>');
document.writeln('typeof document.createElement: ' + typeof document.createElement + '<br>');
</script>
<h3>测试原始的 isFunction 函数方法</h3>
<script>
var isFunction = function( fn, name ) {
return document.writeln('isFunction(' + name + '): ' + (Object.prototype.toString.call(fn) === "[object Function]") + '<br>');
}
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');
</script>
<h3>测试修复后 isFunction 函数方法</h3>
<script>
var isFunction = (function() {
return typeof document.getElementById === "object" ?
isFunction = function(fn, name){
try {
return document.writeln('isFunction(' + name + '): ' + (/^s*function/.test("" + fn)) + '<br>');
} catch (x) {
return document.writeln('isFunction(' + name + '): ' + (false) + '<br>');
}
}:
isFunction = function(fn, name){
return document.writeln('isFunction(' + name + '): ' + ("[object Function]" === Object.prototype.toString.call(fn)) + '<br>');
};
})()
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');
</script>
</body>
</html>
[Ctrl+A 全选 注:
如需引入外部Js需刷新才能执行]
会发现在 IE 下用 typeof 检测 alert、confirm 方法以及 DOM 的方法显示 object,而其他浏览器下显示 function。
那如何完善这个问题呢?
typeof 检测某个方法(例如:document.getElementById) 是否是 object,如何是,则重写 isFunction 函数;
怎样重写呢?正则判断传入的对象字符串后(”" + fn),是否起始位置含有 function,即:/^s*function/.test(” + fn)。
OK,看下根据以上思路修改后的 isFunction 函数:
代码如下:
var isFunction = (function() { // Performance optimization: Lazy Function Definition return "object" === typeof document.getElementById ? isFunction = function(fn){ try { return /^s*function/.test("" + fn); } catch (x) { return false } }: isFunction = function(fn){ return "[object Function]" === Object.prototype.toString.call(fn); };})()
参考阅读:
《isFunction hacked, isCallable solution》
《isFunction() or isObject(), that is the question ? 》
《Lazy Function Definition Pattern》
AKPC_IDS += "376,";
有用 | 无用
猜你喜欢
您可能感兴趣的文章:
- js 右键菜单,支持不同对象不同菜单(兼容IE、Firefox)
- 使用JavaScript库还是自己写代码?
- js或css实现滚动广告的几种方案
- jquery中的sortable排序之后的保存状态的解决方法
- javascript面向对象的方式实现的弹出层效果代码
- js提示信息jtip封装代码,可以是图片或文章
- jquery 常用操作方法
- jquery 经典动画菜单效果代码
- 使用JQuery进行跨域请求
- JavaScript 使用简略语法创建对象的代码
- javascript 的Document属性和方法集合
- 起点页面传值js,有空研究学习下
- javascript 自动标记来自搜索结果页的关键字
- js 多层叠的TAB选项卡
- javascript 三种数组复制方法的性能对比
- javascript下一种表单元素获取方法存在的问题
- js 巧妙去除数组中的重复项
- javascript 删除数组中重复项(uniq)
- 将函数的实际参数转换成数组的方法