Beste Testmethode für eine Funktion in JavaScript?
-
03-07-2019 - |
Frage
Ich habe viel darüber nachgeforscht, aber es scheint, dass die verwendeten Methoden inkonsistent und unterschiedlich sind.
Hier sind einige Methoden, die ich in der Vergangenheit verwendet habe:
/* 1: */ typeof myFunc === 'function'
/* 2: */ myFunc.constructor === Function
/* 3: */ myFunc instanceof Function
Als Teil meiner Forschung habe ich einen Blick darauf, wie einige bekannte Bibliotheken dies erreicht haben:
/* jQuery 1.2.6: */ !!fn && typeof fn != "string" && !fn.nodeName && fn.constructor != Array && /^[\s[]?function/.test( fn + "" )
/* jQuery 1.3b1: */ toString.call(obj) === "[object Function]"
/* Prototype 1.6: */ typeof object == "function"
/* YUI 2.6: */ typeof o === 'function'
Ich bin erstaunt, dass so viele verschiedene Methoden verwendet werden, dass ein einziger akzeptabler Test sicherlich vereinbart wurde? Und ich bin völlig ahnungslos darüber, was die Absichten bei der Wiedergabe von JQuery 1.2.6 waren, sieht ein bisschen Ott aus ...
Mein Quesiton bleibt also, was ist die beste Art zu testen, wie eine Funktion getestet wird?
Ich würde auch einen Einblick in einige der oben genannten Methoden, insbesondere JQuery 1.2.6's, schätzen. (Ich kann sehen, was sie tun, es scheint einfach seltsam)
*] Mit 'Best' meine ich die am weitesten verbreitete Cross-Browser-kompatible Methode.
EDIT: Ja, ich weiß, dass es schon einmal besprochen wurde, aber ich möchte immer noch eine Diskussion über die effektivste Methode. Warum gibt es so viele verschiedene gebrauchte Methoden?
In den bisherigen Diskussionen wurde der Typtyp -Operator (meistens) nur erwähnt, aber niemand hat die Wirksamkeit alternativer Methoden angedeutet.
Lösung
Der beste Weg, um zu testen, ob ein Objekt eine Funktion ist typeof myFunc === 'function'
. Wenn Sie eine Bibliothek verwenden, verwenden Sie den Funktionstest dieser Bibliothek: jQuery.isFunction(myFunc)
.
Dinge kann bei der Verwendung als Funktionen falsch angemeldet werden typeof
. Dies ist sehr selten, aber eine Bibliothek ist da, um diese Inkonsistenzen zu entfernen. JQuery arbeitet um diese Probleme:
- Firefox -Berichte funktionieren mit
typeof document.createElement("object")
- Safari -Berichte funktionieren mit
typeof document.body.childNodes
- Ältere Versionen von Firefox berichteten über regelmäßige Ausdrücke als Funktionen (dies in 3.0 nicht der Fall).
- Einige IE integrierte globale Funktionen (
alert
) und einige Knotenmethoden (getAttribute
) sollen vom Typ "Objekt" sind.
Verwendung instanceof
statt typeof
Umgänge einige davon. Zum Beispiel, document.createElement("object") instanceof Function
ist false
in Firefox.
Sie können die Geburt der ersten Methode in den Kommentaren für sehen das Original -Ticket (#3618). Die neue Methode stammt von Änderungset 5947 und scheint von der Wiederbelebung erfunden worden zu sein, um es zu lösen Dh Speicherlecks. Es ist wahrscheinlich langsamer, aber kleiner und sauberer.
Es gibt keinen großen Unterschied zwischen == und === hier hinsichtlich der Funktionsweise der Dinge, aber die strenge Bewertung ist etwas schneller und somit bevorzugt.
Andere Tipps
John Ressig, der Entwickler von JQuery, scheint einige bizarre Entscheidungen in den Interna JQuery getroffen zu haben.
toString.call(obj) === "[object Function]"
Sieht ziemlich ordentlich aus, aber ich kann mir keine Situation vorstellen, in der das oben genannte wahr wäre, wo das einfache typeof
Ansatz würde scheitern, aber vielleicht weiß er etwas, den der Rest des Gebrauchs nicht tut.
typeof o === "function"
Ich würde mit letzterem gehen, da es größere Klarheit hat, es sei denn, Sie haben starke Beweise dafür, dass es nicht funktioniert.
Warum strikte Gleichheit anwenden? typeof
Da sind beide Operanden Strings? Ich übersehen ein Problem?
Wie auch immer, ich würde die einfachere Art des Typs von Typen machen, was dafür geschehen und lesbar ist. instanceof
ist auch lesbar, aber es scheint mehr darauf zu bestehen, dass eine Funktion ein Objekt ist, was für das Problem irrelevant sein könnte.