However, there are some details that are not well known to us. After analyzing these details, John Resig provided us with a perfect solution, which will be introduced in detail in this article:
1. Unknown details of traditional methods
There is no doubt that in judging For function types, we use the typeof method, for example:
function fn(){
//content
}
alert(typeof fn)//The result is "function".
However, this method does not work as we imagine in some browsers.
1, Firefox2 and Firefox3
In these two browsers, using typeof to detect the type of HTML object element, the result is an imprecise "function" instead of "object", such as HTMLDocument. For example:
alert(typeof HTMLDocument);
/ /In Firefox2 the result is "function";
//In Firefox3 the result is "object";
2, Firefox2 For regular expressions, The result returned in this browser is "function" (the result is "object" in Firefox3), such as:
var reg = /test/;
alert(typeof reg);
//The result is "function" in Firefox2;
//In Firefox3 The result is "object";
Note: I tested it in Safari, and the result is also "function".
3, IE6 and IE7 Using the typeof method on DOM elements in IE, the result is "object". For example:
alert(typeof document.getElementsByTagName("body" )[0].getAttribute);
//The result is "object"
4. Safari 3 Safari believes that the NodeList of DOM elements is a function. For example:
alert(typeof document.body.childNodes);
//The result is "function"
Obviously, if you want to test whether an object is a function, using the typeof method does not guarantee the test result in a true sense. Then, we need a solution that guarantees test results in all browsers. We know that the function itself has two methods, apply() and call(), but these two methods do not exist in the problematic function in IE. Try the following test:
alert(typeof document.getElementsByTagName("body")[0].getAttribute.call)
/ /The result is "undefined" in IE
Obviously, we cannot use these two methods.
2. Perfect solution and implementation process John Resig provided us with a perfect solution. This complex but very stable method of determining whether an object is a function is as follows :
function isFunction( fn ) {
return ! !fn && !fn.nodeName && fn.constructor != String &&
fn.constructor != RegExp && fn.constructor != Array &&
/function/i.test( fn "" );
}
This function first ensures that the test object exists and serializes it into a string containing "function". This is the basis of our detection (fn.constructor != String, fn.constructor != Array, and fn.constructor != RegExp). In addition, we need to ensure that the declared function is not a DOM node (fn.nodeName). Then, we can do the toString test. If we convert a function to a string, (fn "") in a browser gives us the result like this "function name(){...}". Now, determining whether it is a function is as simple as checking whether the string contains the word "function". This works wonders, for any function in question, we get the results we need in all browsers. Compared with the traditional method, the running speed of this function is somewhat unsatisfactory. The author recommends that we use it conservatively.
John Resig is the developer of the jQuery library. I believe that friends who use this library are familiar with its concise syntax and excellent performance. In addition to pursuing code simplicity and efficient performance, the author's spirit of perfection is also impressive. If you are a perfectionist, I believe this article will be helpful to you.