However, we are not familiar with some details. After analyzing these details, John Resig provides us with a perfect solution. This article will introduce in detail:
I. Unknown details about traditional methods
Undoubtedly, when determining the function type, we use the typeof method, for example:
Copy codeThe Code is as follows:
Function fn (){
// Content
}
Alert (typeof fn) // The result is "function ".
However, this method does not work as we imagined in Some browsers.
1. Firefox2 and Firefox3
In these two browsers, typeof is used to detect the type of HTML object elements and obtain an inaccurate "function" result, rather than "object", such as HTMLDocument. For example:
Copy codeThe Code is as follows:
Alert (typeof HTMLDocument );
// In Firefox2, the result is "function ";
// The result in Firefox3 is "object ";
2. Firefox2
For a regular expression, the result returned in the browser is "function" (the result in Firefox3 is "object"), for example:
Copy codeThe Code is as follows:
Var reg =/test /;
Alert (typeof reg );
// In Firefox2, the result is "function ";
// The result in Firefox3 is "object ";
Note: I tested it in safari and the result is "function ".
3. IE6 and IE7
Use the typeof Method for DOM elements in IE. The result is "object ". For example:
Copy codeThe Code is as follows:
Alert (typeof document. getElementsByTagName ("body") [0]. getAttribute );
// The result is "object"
4. Safari 3
Safari considers the DOM element's NodeList as a function, such:
Copy codeThe Code is as follows:
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 actually guarantee the test result. Therefore, we need a solution that ensures 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 functions with errors in IE. Try the following test:
Copy codeThe Code is as follows:
Alert (typeof document. getElementsByTagName ("body") [0]. getAttribute. call)
// In IE, the result is "undefined"
Obviously, we cannot use these two methods.
2. Perfect solution and implementation process
John Resig provides us with a perfect solution. This complicated but stable method for determining whether an object is a function is as follows:
Copy codeThe Code 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 the existence of the test object 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 test toString. If we convert a function into a string, the result (fn + "") in a browser is like this "function name (){...}". Now, it is easy to determine whether it is a function. You only need to determine whether the string contains the word "function ". This is amazing. For any problematic function, we can get the results we need in all browsers. This function is less efficient than the traditional method, and we suggest using it conservatively.
John Resig is a developer of the jQuery library. I believe friends who use this library are familiar with the concise syntax and excellent performance of this library. In addition to concise code and efficient performance, the author's spirit of perfection is also amazing. If you are a perfectionist, I believe this article is very helpful to you.