Bei der Beurteilung des Funktionstyps verwenden wir normalerweise die Methode typeof. Unter normalen Umständen erzielt sie den erwarteten Effekt. Es gibt jedoch einige Details, die uns nicht genau bekannt sind. Nach der Analyse dieser Details lieferte uns John Resig eine perfekte Lösung, die in diesem Artikel ausführlich vorgestellt wird:
1. Unbekannte Details traditioneller Methoden
Es besteht kein Zweifel, dass wir bei der Bestimmung des Funktionstyps die Methode typeof verwenden, wie zum Beispiel:
Funktion fn(){
//Inhalt
}
alarm(typeof fn)//Das Ergebnis ist „Funktion“.
Allerdings funktioniert diese Methode in einigen Browsern nicht wie erwartet.
1. Firefox2 und Firefox3
In diesen beiden Browsern führt die Verwendung von typeof zur Erkennung des Typs eines HTML-Objektelements zu einem ungenauen „Funktions“-Ergebnis anstelle von „Objekt“, wie z. B. HTMLDocument. wie:
alarm(typeof HTMLDocument);
//In Firefox2 ist das Ergebnis „function“;
//In Firefox3 ist das Ergebnis „object“;
2. Firefox2
Bei regulären Ausdrücken ist das in diesem Browser zurückgegebene Ergebnis „Funktion“ (das Ergebnis ist „Objekt“ in Firefox3), wie zum Beispiel:
var reg = /test/;
alarm(typeof reg);
//In Firefox2 ist das Ergebnis „function“;
//In Firefox3 ist das Ergebnis „object“;
Hinweis: Ich habe es in Safari getestet und das Ergebnis war ebenfalls „Funktion“.
3. IE6 und IE7
Wenn Sie die Methode „typeof“ für ein DOM-Element im IE verwenden, ist das Ergebnis „Objekt“. wie:
Alert(typeof document.getElementsByTagName("body")[0].getAttribute);
//Das Ergebnis ist „Objekt“
4. Safari 3
Safari geht davon aus, dass die NodeList von DOM-Elementen eine Funktion ist, wie zum Beispiel:
alarm(typeof document.body.childNodes);
//Das Ergebnis ist „Funktion“
Wenn Sie testen möchten, ob ein Objekt eine Funktion ist, garantiert die Verwendung der Methode „typeof“ natürlich nicht das Testergebnis im eigentlichen Sinne. Dann brauchen wir eine Lösung, die Testergebnisse in allen Browsern garantiert. Wir wissen, dass die Funktion selbst zwei Methoden hat, apply() und call(), aber diese beiden Methoden sind in der problematischen Funktion im IE nicht vorhanden. Versuchen Sie den folgenden Test:
Alert(typeof document.getElementsByTagName("body")[0].getAttribute.call)
//Das Ergebnis ist im IE „undefiniert“.
Offensichtlich können wir diese beiden Methoden nicht nutzen.
2. Perfekter Lösungs- und Implementierungsprozess
John Resig lieferte uns eine perfekte Lösung. Diese komplexe, aber stabile Methode zur Bestimmung, ob ein Objekt eine Funktion ist, lautet wie folgt:
Funktion isFunction( fn ) {
return !!fn && !fn.nodeName && fn.constructor != String &&
fn.constructor != RegExp && fn.constructor != Array &&
/function/i.test( fn + "" );
}
Diese Funktion stellt zunächst sicher, dass das Testobjekt vorhanden ist, und serialisiert es in einen String, der „function“ enthält. Dies ist die Grundlage unserer Erkennung (fn.constructor != String, fn.constructor != Array und fn.constructor != RegExp). . Darüber hinaus müssen wir sicherstellen, dass die deklarierte Funktion kein DOM-Knoten (fn.nodeName) ist. Dann können wir den toString-Test durchführen. Wenn wir eine Funktion in einen String konvertieren, erhalten wir in einem Browser (fn+"") das Ergebnis wie folgt: "Funktionsname(){...}". Um nun festzustellen, ob es sich um eine Funktion handelt, müssen Sie nur prüfen, ob die Zeichenfolge das Wort „Funktion“ enthält. Das wirkt Wunder, denn für jede fragliche Funktion erhalten wir in allen Browsern die Ergebnisse, die wir brauchen. Im Vergleich zur herkömmlichen Methode ist die Ausführungsgeschwindigkeit dieser Funktion etwas unbefriedigend. Der Autor empfiehlt, sie konservativ zu verwenden.
John Resig ist der Entwickler der jQuery-Bibliothek. Ich glaube, dass Freunde, die diese Bibliothek verwenden, mit ihrer prägnanten Syntax und hervorragenden Leistung vertraut sind. Neben dem Streben nach Code-Einfachheit und hoher Leistung ist auch der Perfektionsgeist des Autors beeindruckend. Wenn Sie ein Perfektionist sind, glaube ich, dass dieser Artikel für Sie hilfreich sein wird.
Originaltext: http://www.denisdeng.com/?p=426