In meinem speziellen Fall:
callback instanceof Function
oder
typeof callback == "function"
Ist es überhaupt wichtig, was ist der Unterschied?
Zusätzliche Ressource:
JavaScript-Garden typeof vs instanceof
javascript
instanceof
typeof
Farinspace
quelle
quelle
Object.prototype.toString
ecma-international.org/ecma-262/6.0/….constructor
stattdessen einfach die Eigenschaft.Antworten:
Verwendung
instanceof
für benutzerdefinierte Typen:Verwendung
typeof
für einfache eingebaute Typen:Verwendung
instanceof
für komplexe eingebaute Typen:Und der letzte ist ein bisschen knifflig:
quelle
Use instanceof for complex built in types
- Dies ist immer noch fehleranfällig. Besser ES5Array.isArray()
et al. oder die empfohlenen Unterlegscheiben.Beide sind in ihrer Funktionalität ähnlich, da beide Typinformationen zurückgeben. Ich persönlich bevorzuge
instanceof
es jedoch, weil sie tatsächliche Typen anstelle von Zeichenfolgen vergleichen. Der Typvergleich ist weniger anfällig für menschliches Versagen und technisch schneller, da Zeiger im Speicher verglichen werden, anstatt Vergleiche mit ganzen Zeichenfolgen durchzuführen.quelle
Ein guter Grund für die Verwendung von typeof ist, wenn die Variable möglicherweise undefiniert ist.
Ein guter Grund für die Verwendung von instanceof ist, wenn die Variable null sein kann.
Meiner Meinung nach hängt es also wirklich davon ab, welche Art von möglichen Daten Sie überprüfen.
quelle
instanceof
nicht mit primitiven Typen zu vergleichen ist, typeof can.undefined instanceof Object
false zurück und löst keine Ausnahme aus. Ich weiß nicht, wie aktuell diese Änderung ist, aber sie machtinstanceof
attraktiver.undefined instanceof Object
löst keine Ausnahme aus, weil ehundefined
definiert ist. Die Konstante existiert im Namespace. Wenn eine Variable nicht vorhanden ist (z. B. aufgrund eines Tippfehlers), löst instanceof eine Ausnahme aus. Die Verwendung von typeof für eine nicht vorhandene Variable ergibt andererseits 'undefined'.Um die Dinge klar zu machen, müssen Sie zwei Fakten kennen:
Object.setPrototypeOf()
Methode (ECMAScript 2015) oder nach__proto__
Eigenschaft (alte Browser, veraltet) festgelegt werden. Das Ändern des Prototyps eines Objekts wird aus Leistungsgründen jedoch nicht empfohlen.Somit gilt instanceof nur für Objekte. In den meisten Fällen verwenden Sie keine Konstruktoren, um Zeichenfolgen oder Zahlen zu erstellen. Du kannst. Aber das tust du fast nie.
Auch instanceof kann nicht genau prüfen, welcher Konstruktor zum Erstellen des Objekts verwendet wurde, gibt jedoch true zurück, selbst wenn das Objekt von der zu überprüfenden Klasse abgeleitet ist. In den meisten Fällen ist dies das gewünschte Verhalten, manchmal jedoch nicht. Also musst du diesen Geist behalten.
Ein weiteres Problem besteht darin, dass unterschiedliche Bereiche unterschiedliche Ausführungsumgebungen haben. Dies bedeutet, dass sie unterschiedliche integrierte Funktionen haben (unterschiedliche globale Objekte, unterschiedliche Konstruktoren usw.). Dies kann zu unerwarteten Ergebnissen führen.
Zum Beispiel
[] instanceof window.frames[0].Array
wird zurückkehrenfalse
, weilArray.prototype !== window.frames[0].Array
und Arrays aus dem ehemaligen erben.Es kann auch nicht für undefinierte Werte verwendet werden, da es keinen Prototyp hat.
Lassen Sie uns jetzt über eine schwierige Sache sprechen. Was ist, wenn Sie den Konstruktor verwenden, um einen primitiven Typ zu erstellen?
Scheint wie Magie. Aber es ist nicht. Es ist das sogenannte Boxen (Umschließen des primitiven Werts nach Objekt) und das Unboxing (Extrahieren des umschlossenen primitiven Werts aus dem Objekt). Eine solche Art von Code scheint "ein bisschen" zerbrechlich zu sein. Natürlich können Sie es einfach vermeiden, mit Konstruktoren einen primitiven Typ zu erstellen. Aber es gibt noch eine andere mögliche Situation, in der das Boxen Sie treffen kann. Wenn Sie Function.call () oder Function.apply () für einen primitiven Typ verwenden.
Um dies zu vermeiden, können Sie den strengen Modus verwenden:
upd: Seit ECMAScript 2015 gibt es einen weiteren Typ namens Symbol, der einen eigenen Typ von == "Symbol" hat .
Sie können darüber auf MDN lesen: ( Symbol , Typ ).
quelle
if an object is created by a given constructor
Das ist falsch.o instanceof C
wird true zurückgeben, wenn o von C.prototype erbt. Sie haben später in Ihrer Antwort etwas darüber erwähnt, aber es ist nicht sehr klar.Ich habe in Safari 5 und Internet Explorer 9 ein wirklich interessantes (als "schrecklich" bezeichnetes) Verhalten entdeckt. Ich habe es in Chrome und Firefox mit großem Erfolg verwendet.
Dann teste ich in IE9 und es funktioniert überhaupt nicht. Große Überraschung. Aber in Safari ist es zeitweise! Also beginne ich mit dem Debuggen und stelle fest, dass Internet Explorer immer wieder zurückkehrt
false
. Aber das Seltsamste ist, dass Safari anscheinend eine Art Optimierung in seiner JavaScript-VM vornimmt, wo estrue
das erste Mal ist, aber jedes Mal , wennfalse
Sie auf "Neu laden" klicken!Mein Gehirn explodierte fast.
Jetzt habe ich mich also darauf geeinigt:
Und jetzt funktioniert alles super. Beachten Sie, dass Sie aufrufen können
"a string".toString()
und nur eine Kopie der Zeichenfolge zurückgibt, d. H.Also werde ich von nun an beide verwenden.
quelle
Sonstige wesentliche praktische Unterschiede:
quelle
instanceof
funktioniert auch, wenncallback
ein Subtyp von istFunction
, denke ichquelle
instanceof
in Javascript kann schuppig sein - ich glaube, große Frameworks versuchen, seine Verwendung zu vermeiden. Verschiedene Fenster sind eine der Möglichkeiten, wie sie brechen können - ich glaube, Klassenhierarchien können es auch verwirren.Es gibt bessere Möglichkeiten, um zu testen, ob ein Objekt ein bestimmter integrierter Typ ist (was normalerweise gewünscht wird). Erstellen Sie Dienstprogrammfunktionen und verwenden Sie sie:
Und so weiter.
quelle
instanceof
wird nicht für Grundelemente funktionieren, z. B."foo" instanceof String
wird zurückkehren,false
währendtypeof "foo" == "string"
wird zurückkehrentrue
.Auf der anderen Seite
typeof
wird es wahrscheinlich nicht das tun, was Sie wollen, wenn es um benutzerdefinierte Objekte (oder Klassen, wie auch immer Sie sie nennen möchten) geht. Zum Beispiel:Es kommt einfach so vor, dass Funktionen sowohl 'Funktions'-Primitive als auch Instanzen von' Funktion 'sind, was etwas seltsam ist, da es für andere primitive Typen, z.
aber
quelle
Ich würde die Verwendung von Prototypen empfehlen
callback.isFunction()
.Sie haben den Unterschied herausgefunden und Sie können sich auf ihren Grund verlassen.
Ich denke, andere JS-Frameworks haben auch solche Dinge.
instanceOf
Ich glaube, ich würde nicht an Funktionen arbeiten, die in anderen Fenstern definiert sind. Ihre Funktion unterscheidet sich von Ihrerwindow.Function
.quelle
Bei der Suche nach einer Funktion muss immer verwendet werden
typeof
.Hier ist der Unterschied:
Deshalb darf man niemals
instanceof
nach einer Funktion suchen.quelle
typeof
dass es falsch ist -f
ist alles Folgendes: einObject
(ein Objekt) und einFunction
(eine Funktion). Mit Ausnahme von mir ist die Verwendung sinnvoller,instanceof
da ich weiß, dass es sich um eine Funktion handelt, von der ich weiß, dass es sich auch um ein Objekt handelt, da alle Funktionen Objekte in ECMAScript sind. Das Gegenteil ist nicht wahr - aus dem Wissen ,typeof
dassf
ist in der Tat einobject
Ich habe keine Ahnung , dass es auch eine Funktion.length
,name
undcall
von Funktion, aber alle von ihnen sind nicht mehr. Was noch schlimmer ist, es kann nicht aufgerufen werden und dasTypeError
sagt es :f is not a function
.Wesentlicher praktischer Unterschied:
Frag mich nicht warum.
quelle
str
ist ein String-Grundelement, kein String-Objekt. Das Gleiche gilt für Zahlenprimitive und Boolesche Grundelemente. Sie sind keine Instanzen ihrer "konstruierten" Gegenstücke, der String-, Zahlen- und Booleschen Objekte. JavaScript konvertiert diese drei Grundelemente bei Bedarf automatisch in Objekte (z. B. mithilfe einer Methode in der Prototypenkette des Objekts). Auf der anderen Seite Ihres praktischen Unterschieds ist instanceof seitdem besser für die Suche nach Arrays geeignettypeof [] == "object" // true
.Performance
typeof
ist schneller alsinstanceof
in Situationen, in denen beide anwendbar sind.Abhängig von Ihrem Motor kann der Leistungsunterschied zugunsten von
typeof
etwa 20% liegen . ( Ihr Kilometerstand kann variieren )Hier ist ein Benchmark-Test für
Array
:Ergebnis
quelle
instanceof
immer der Prototypenkette des Objekts, sodass die Leistungsbeeinträchtigung davon abhängt, inwieweit in der Prototypenkette die Klasseinstanceof
getestet wird. Für eine kurze Vererbungskette ist die Strafe also niedriger (wie[] instanceof Array
,,{} instanceof Object
) und für lange - größer. Wenn also beideobj instanceof SomeClass
undtypeof obj !== 'string'
aus der Sicht einiger Ihrer hypothetischen Codes dasselbe bedeuten (z. B. wenn Sie nur einen Test durchführenif
und nichtswitch
mehrere Klassen durchlaufen usw.), sollten Sie in Bezug auf die Leistung die zweite auswählen.Dies ist nur eine Ergänzung zu allen anderen Erklärungen hier - ich schlage nicht vor , sie
.constructor
überall zu verwenden .TL; DR: In Situationen, in denen dies
typeof
keine Option ist und Sie wissen, dass Sie sich nicht für die Prototypenkette interessieren ,Object.prototype.constructor
kann dies eine praktikable oder sogar bessere Alternative sein alsinstanceof
:Es ist seit 1.1 im Standard, also keine Sorge um die Abwärtskompatibilität.
Muhammad Umer erwähnte dies auch hier irgendwo in einem Kommentar kurz. Es funktioniert auf alles mit einem Prototyp - also alles nicht
null
oderundefined
:Darüber hinaus kann es je nach Anwendungsfall viel schneller sein als
instanceof
(der Grund dafür ist wahrscheinlich, dass nicht die gesamte Prototypenkette überprüft werden muss). In meinem Fall brauchte ich einen schnellen Weg, um zu überprüfen, ob ein Wert ein typisiertes Array ist:https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
Und die Ergebnisse:
Chrome 64.0.3282.167 (64-Bit, Windows)
Firefox 59.0b10 (64-Bit, Windows)
Aus Neugier habe ich einen schnellen Spielzeug-Benchmark durchgeführt
typeof
; überraschenderweise ist die Leistung nicht viel schlechter und in Chrome scheint es sogar noch ein bisschen schneller zu sein:https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
HINWEIS: Die Reihenfolge, in der die Funktionen aufgelistet sind, wechselt zwischen den Bildern!
Chrome 64.0.3282.167 (64-Bit, Windows)
Firefox 59.0b10 (64-Bit, Windows)
HINWEIS: Die Reihenfolge, in der die Funktionen aufgelistet sind, wechselt zwischen den Bildern!
quelle
Verwenden Sie instanceof, da beim Ändern des Klassennamens ein Compilerfehler angezeigt wird.
quelle
quelle
Ich komme aus einer strengen OO-Erziehung, für die ich mich entscheiden würde
Strings sind anfällig für meine schreckliche Rechtschreibung oder andere Tippfehler. Außerdem finde ich, dass es besser liest.
quelle
Obwohl Instanz ein bisschen schneller als Typ ist , bevorzuge ich wegen einer solchen möglichen Magie die zweite:
quelle
Ein weiterer Fall ist, dass Sie nur mit sortieren können
instanceof
- es gibt true oder false zurück. Mittypeof
können Sie Art von etwas zur Verfügung gestellt bekommenquelle
Mit Blick auf die Leistung sollten Sie typeof besser mit einer typischen Hardware verwenden. Wenn Sie ein Skript mit einer Schleife von 10 Millionen Iterationen erstellen, dauert die Anweisung typeof str == 'string' 9 ms, während die 'string'-Instanz von String 19 ms dauert
quelle
Natürlich ist es wichtig ........!
Lassen Sie uns dies anhand von Beispielen durchgehen. In unserem Beispiel werden wir die Funktion auf zwei verschiedene Arten deklarieren.
Wir werden beide
function declaration
und Function Constructor verwenden . Wir werden sehen, wietypeof
und wie wir unsinstanceof
in diesen beiden unterschiedlichen Szenarien verhalten.Funktion mit Funktionsdeklaration erstellen:
Mögliche Erklärung für ein solches anderes Ergebnis ist, wie wir eine Funktion Erklärung,
typeof
kann verstehen , dass es sich um eine function.Because isttypeof
überprüft , ob der Ausdruck auf dem typeof Betrieb ist, in unserem Fall implementiert Call - Methode oder nicht . Wenn es eine Methode implementiert , handelt es sich um eine Funktion. Andernfalls nicht. Zur Verdeutlichung überprüfen Sie die Ecmascript-Spezifikation auf den TypMyFunc
Call
.Erstellen Sie eine Funktion mit dem Funktionskonstruktor:
Hier
typeof
behauptet , dassMyFunc2
eine Funktion sowie dieinstanceof
operator.We bereits weiß , zutypeof
überprüfen , obMyFunc2
implementiertCall
Methode oder not.AsMyFunc2
eine Funktion ist , und es implementiertcall
Methode, das ist , wietypeof
weiß , dass es ein function.On ist die andere Hand, verwenden wirfunction constructor
zu schaffen , umMyFunc2
es wird zu einer Instanz vonFunction constructor
. Deshalb wirdinstanceof
auch aufgelösttrue
.Was ist sicherer zu verwenden?
Wie wir in beiden Fällen sehen
typeof
können, kann der Bediener erfolgreich behaupten, dass es sich hier um eine Funktion handelt, die sicherer ist alsinstanceof
.instanceof
wird im Falle von scheitern,function declaration
weilfunction declarations
keine Instanz von sindFunction constructor
.Beste Übung :
Wie Gary Rafferty vorgeschlagen hat, sollte der beste Weg darin bestehen, sowohl typeof als auch instanceof zusammen zu verwenden.
quelle
Um genau zu sein, sollte eine Instanz verwendet werden, bei der Wert über den Konstruktor erstellt wird (im Allgemeinen benutzerdefinierte Typen), z
während typeof , um Werte zu überprüfen, die nur durch Zuweisungen für z
quelle
Sie müssen nicht mit einer Menge der oben genannten Beispiele überhäufen. Denken Sie nur an zwei Gesichtspunkte:
typeof var;
ist ein unärer Operator, der den ursprünglichen Typ oder Root-Typ von var zurückgibt. so dass es vom Urtyp zurückkehren (string
,number
,bigint
,boolean
,undefined
, undsymbol
) oderobject
Typ.Bei übergeordneten Objekten wie integrierten Objekten (String, Number, Boolean, Array ..) oder komplexen oder benutzerdefinierten Objekten handelt es sich bei allen Objekten um
object
Stammtypen. Der darauf basierende Instanztyp ist jedoch unterschiedlich (wie bei der OOP-Klasse) Vererbungskonzept), hiera instanceof A
- ein binärer Operator - hilft Ihnen, er durchläuft die Prototypenkette, um zu überprüfen, ob der Konstruktor des richtigen Operanden (A) erscheint oder nicht.Wenn Sie also "Root-Typ" überprüfen oder mit primitiven Variablen arbeiten möchten, verwenden Sie "typeof", andernfalls "instanceof".
null
ist ein Sonderfall, der scheinbar primitiv ist, aber in der Tat ein Sonderfall für Objekt. Verwendena === null
Sie stattdessen, um null zu überprüfen.Auf der anderen Seite
function
ist auch ein Sonderfall, der ein eingebautes Objekt ist, abertypeof
zurückgibtfunction
Wie Sie sehen,
instanceof
muss die Prototypenkette in der Zwischenzeittypeof
nur einmal den Wurzeltyp überprüfen, damit leicht zu verstehen ist, warum diestypeof
schneller ist alsinstanceof
quelle
Gemäß der MDN-Dokumentation zu typeof sind Objekte, die mit dem Schlüsselwort "new" instanziiert wurden, vom Typ "object":
Während die Dokumentation über Instanz von Punkten, dass:
Wenn man also überprüfen möchte, ob etwas eine Zeichenfolge ist, unabhängig davon, wie es erstellt wurde, ist es am sichersten, es zu verwenden
instanceof
.quelle