Side navigation
#2968 closed bug (fixed)
Opened June 02, 2008 03:48PM UTC
Closed July 23, 2008 04:18PM UTC
Last modified March 14, 2012 05:00PM UTC
isFunction and object problems
| Reported by: | Andrea Giammarchi | Owned by: | flesler |
|---|---|---|---|
| Priority: | major | Milestone: | 1.3 |
| Component: | core | Version: | 1.2.6 |
| Keywords: | isFunction | Cc: | |
| Blocked by: | Blocking: |
Description
Version 1.2.6 of jQuery has a public static isFunction method that fails in some case.
These are only two cases:
jQuery.isFunction(new String("function")); // true
jQuery.isFunction({toString:function(){return "function"}}); // true
jQuery.isFunction({valueOf:function(){return "function"}}); // true
At the same time, every compatible browser, IE a part, could simply use this function:
isFunction:function(fn){return fn && fn instanceof Function}
that seems to work as expected with every unit test case.
My suggestion is to implement latter function for Firefox, Opera, and Safari, plus a dedicated one for IE:
isFunction: jQuery.browser.msie ?
function( fn ) {
if( !fn )
return false;
var s = "toString",
v = "valueOf",
t = typeof fn[s] === "function" && fn[s],
o = typeof fn[v] === "function" && fn[v],
r;
if( t )
delete fn[s];
if( o )
delete fn[v];
r = typeof fn !== "string" && !(fn instanceof String) && !fn.nodeName && fn.constructor != Array && /^[\\s[]?function/.test(fn + "");
if( t )
fn[s] = t;
if( o )
fn[v] = o;
return r;
} :
function( fn ) {
return fn && fn instanceof Function;
},
The only problem is that browser object property is assigned too late, but since it does not depend on jQuery, I suggest to move its assignment on the top of the library, to let other methods use a direct assignment strategy, like above one, instead of a lazy one.
Above code has been tested with every compatible IE, plus Opera 9 and Safari 3 ( I could not test Safari 2 yet )
Kind Regards
Attachments (2)
Change History (9)
Changed June 04, 2008 03:56PM UTC by comment:1
| owner: | → flesler |
|---|---|
| status: | new → assigned |
Changed June 04, 2008 05:28PM UTC by comment:2
Just a note, flesler, to respect return boolean value, other browsers could better use this one:
function( fn ) {
return !!fn && fn instanceof Function;
}
so null or undefined will be returned as false
Changed June 04, 2008 07:42PM UTC by comment:3
flesler ... I have just realized that first check is not useful ... so this is my last proposal that speedup IE too in an optimistic way:
isFunction: jQuery.browser.msie ?
function( fn ) {
if( fn instanceof Function )
return true;
if( !fn )
return false;
var s = "toString",
v = "valueOf",
t = typeof fn[s] === "function" && fn[s],
o = typeof fn[v] === "function" && fn[v],
r;
if( t )
delete fn[s];
if( o )
delete fn[v];
r = typeof fn !== "string" && !(fn instanceof String) && !fn.nodeName && fn.constructor != Array && /^[\\s[]?function/.test(fn + "");
if( t )
fn[s] = t;
if( o )
fn[v] = o;
return r;
} :
function( fn ) {
return fn instanceof Function;
},
hiping this will help you and will be a "definitive" solution :)
Changed July 08, 2008 12:00AM UTC by comment:4
as I wrote in the ML, please try this code too:
isFunction:function( fn ){
return !!fn && (fn instanceof Function || (typeof fn == "object" && !(fn instanceof Object)));
}
that with a browser based implementation, to avoid last useless check, could be:
isFunction:jQuery.browser.msie?
function( fn ){
return !!fn && (fn instanceof Function || (typeof fn == "object" && !(fn instanceof Object)));
}:
function( fn ){
return fn instanceof Function;
}
Regards
Changed July 08, 2008 10:33AM UTC by comment:5
Above suggestions fail with different IE cases. Please consider this last piece of code that after some test, seems to be the best one for IE.
isFunction : jQuery.browser.msie ?
function( fn ){
return !!fn && (fn instanceof Function || (fn instanceof ActiveXObject && /\\[native code\\]/.test(fn + "")));
}:
function( fn ){
return fn instanceof Function;
}
Hoping this will be the last proposal, I am going to test unit cases.
Kind Regards
Changed July 22, 2008 04:53PM UTC by comment:6
By using:
function( fn ) {
return fn instanceof Function;
}
All tests pass on FF and IE only fails on DOM methods (input.focus, foo.getAttribute).
I think this is good enough, it will surely bump perfomance.
I can't imagine a situation where one would separate DOM methods from their node to pass them as argument.
Changed July 23, 2008 04:18PM UTC by comment:7
| need: | Review → Commit |
|---|---|
| resolution: | → fixed |
| status: | assigned → closed |
| version: | 1.2.5 → 1.2.6 |
Applied at [5792].
Commented out 2 tests, and the suite passes on all major browsers.