适应jQuery的isFunction方法
isFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
}
InternetExlorer 8返回以下错误:“对象不支持此属性或方法”。 A good article挖掘此函数不会解决此问题。为了检查是否定义了 obj ,我更改了参考to the MSDN article中的函数:
isFunction: function( obj ) {
return obj && toString.call(obj) === "[object Function]";
}
解决方案的其他任何想法?
答案 0 :(得分:9)
您需要直接从toString
对象调用Object.prototype
方法:
function isFunction (obj) {
return Object.prototype.toString.call(obj) === "[object Function]";
}
alert(isFunction({})); // false
alert(isFunction(function{})); // true
jQuery有一个名为toString
的局部变量,它引用Object.prototype
上的方法。
仅调用toString.call(obj);
而不在范围上声明toString
标识符,适用于Firefox,Chrome等,因为Global对象继承自Object.prototype
,但这不能保证规格。
Object.prototype.isPrototypeOf(window); // false on IE
您链接的文章讨论了ECMAScript第5版规范中引入的call
和apply
方法的更改。
这些方法允许您调用一个函数,将第一个参数作为被调用函数的this
值传递。
在ECMAScript 3上,如果此参数为undefined
或null
,则调用函数的this
值将引用全局对象,例如:
function test () { return this; }
test.call(null) === window; // true
但是在ES5中发生了变化,现在应该不经修改地传递该值,这导致Object.prototype.toString
抛出异常,因为期望对象参数。
该方法的规范已更改,现在,如果this
值引用undefined
或null
,则会返回字符串"[object Undefined]"
或"[object Null]"
,问题(我认为不是很好的事情,因为两个结果都是错误的,undefined
和null
是不是对象,它们是原始的......这让我记住了typeof null == 'object'
...而且我认为它与[[Class]]
内部属性的概念混淆了,无论如何......)
现在您可能想知道为什么jQuery使用此方法来检查函数对象,而不是使用typeof
运算符?
实施错误,例如在Chrome / Safari / WebKit中,RegExp对象的typeof
返回"function"
,因为RegExp对象使可调用,例如:
typeof /foo/; // "function" in Chrome/Safari/WebKit
如果对象实现了typeof
内部属性,"function"
运算符返回[[Call]]
,这使得对象可调用。
这最初是由Mozilla实现引入的,调用RegExp对象相当于调用exec
方法。
答案 1 :(得分:1)
isFunction
函数试图服务的目的是什么?它是打算处理宿主对象(即浏览器中的DOM节点,window
等),还是正则表达式(正如CMS在评论中指出的那样是可调用的,并返回带有typeof
的“函数”一些浏览器)?如果没有,您只需要
typeof obj == "function"
如果它应该处理主机方法,那么它是有缺陷的,因为浏览器没有义务为主机方法返回“[object Function]”。在IE中有许多可调用的主机属性,它们不会返回“[object Function]”或将引发错误。例如:
alert(Object.prototype.toString.call(document.createElement));
...在IE中给出“[object Object]”。
答案 2 :(得分:-1)
我刚刚在IE 8的控制台中运行了这个:
>>$.isFunction(undefined);
false
工作正常。
您引用的博客文章涉及IE 9 。