HintergrundWie wir alle wissen, ist js eine dynamische, schwach typisierte Skriptsprache, die ein dynamisches Typsystem und prototypbasierte Vererbung verwendet. Das Fehlen statischer Einschränkungen für Typen bedeutet, dass durch Datentypen verursachte Programmfehler während der Kompilierungsphase nicht rechtzeitig entdeckt werden können. Um robusten Code zu schreiben, müssen zur Laufzeit verschiedene Prüfungen und Kompatibilitäten durchgeführt werden. Daher ist die Fähigkeit, Datentypen geschickt und genau zu erkennen, zu einer der wichtigsten Grundlagen für die Beherrschung dieser Sprache geworden. Welche Methoden gibt es zur Bestimmung von Datentypen?Im Allgemeinen gibt es ungefähr die folgenden Typen: typeof, instanceof, Object.prototype.toString, Konstruktor, Duck-Typing und Erkennungsmethoden für bestimmte Typen Array.isArray(), Number.isNaN(). Obwohl es viele Methoden gibt, sind ihre Verwendungsszenarien unterschiedlich. 1. Verwenden Sie typeof, um den grundlegenden Datentyp zu bestimmen:Die Rückgabewerte sind undefiniert, Zeichenfolge, Zahl, Boolescher Wert, Objekt, Funktion und Symbol. Es ist ersichtlich, dass typeof als offiziell bereitgestellter Typerkennungsoperator sehr zuverlässig grundlegende Datentypen und Funktionen wie undefined, String, Boolean und Symbol erkennt. Der Hauptgrund für die schlechte Leistung ist
Defekt 2) lässt sich vermeiden, indem bei der Typbestimmung der Objektreferenz ein weiterer Satz hinzugefügt wird: typeof x === 'object' && x !== null. Allerdings stellt die Unfähigkeit, zwischen den einzelnen Objekttypen zu unterscheiden, tatsächlich ein großes Problem dar. 2. Verwenden Sie instanceof, um den Objektdatentyp zu bestimmenMit diesem Operator wird festgestellt, ob der Prototyp eines Konstruktors in der Prototypenkette des Zielobjekts vorkommt. Dies ist eine prädiktive Erkennungsmethode. Sie gibt den Datentyp nicht direkt als Zeichenfolge zurück wie typeof. Stattdessen müssen Sie den Konstruktor des Objekttyps vorhersagen und schließlich einen booleschen Wert zurückgeben. Die Erkennungsregel ist eigentlich aus dem Namen ersichtlich, der bestimmt, ob die Instanz von einem bestimmten Konstruktor erstellt wird. Nachdem wir nun das Prinzip kennen, implementieren wir unsere eigene Instanz von. Funktion myInstanceof(Ziel,Konstruktor){ const baseType = ['Zeichenfolge', 'Zahl', 'Boolescher Wert', 'undefiniert', 'Symbol'] wenn (Basistyp.includes(Typ von(Ziel))) { return false } //Die Prototypenkette ist eigentlich eine verknüpfte Liste, die aus Objekten besteht. Durchlaufen Sie diese verknüpfte Liste, let Prototyp = Object.getPrototypeOf(Ziel); während(Prototyp){ //Sobald es ein passendes Objekt in der Kette gibt, geben Sie true zurück. wenn (Prototyp === Konstruktor.Prototyp) { returniere wahr }anders{ Prototyp = Objekt.getPrototypeOf(Prototyp) } } return false } console.log(meineInstanzvon([],Array)) In js können wir im Großen und Ganzen davon ausgehen, dass alles von Objekten stammt, denn obwohl Instanzen durch Konstruktoren erstellt werden, ist der Konstruktor selbst nur eine emotionslose Produktionsmaschine. Die Seele und der Charakter (öffentliche Eigenschaften und Methoden) der Instanz werden alle vom Prototypobjekt geteilt, auf das die Prototypeigenschaft des Konstruktors zeigt, und Prototypobjekte sind alle reine Objekte, die vom Objektkonstruktor erstellt werden, was die folgenden Konsequenzen hat. Bei Arrays wird beim Durchlaufen der Objekte in der Prototypkette Array.prototype Object.prototype angezeigt. Darüber hinaus ist es unmöglich, die durch Literalwerte erstellten Basisdatentypen zu beurteilen. Zum Beispiel Wie können die oben genannten Mängel ausgeglichen werden? Die Antwort besteht darin, in den oben genannten speziellen Szenarien anstelle von instanceof den folgenden Konstruktor zu verwenden. 3. Verwenden Sie das Konstruktorattribut Lassen Sie uns zunächst eines klarstellen. Der Konstruktor ist eine Eigenschaft des Prototyps, und die Instanz erbt vom Prototyp, sodass auf diese Eigenschaft auch direkt in der Instanz zugegriffen werden kann. Unerwartet gute Leistung, mit Ausnahme von null und undefiniert kann der Basistyp (Wrappertyp) oder Objekttyp mit einem Konstruktorattribut genau beurteilt werden. Es kann Array|Object genau unterscheiden, da es nicht wie instanceof die gesamte Prototypenkette durchläuft, sondern nur Urteile über die Instanz vornimmt. Es gibt jedoch auch einen schwerwiegenden Fehler. Dieses Attribut der Instanz kann zu leicht geändert werden. Nach der Änderung wird diese Methode bedeutungslos. 4. toString-MethodeZunächst einmal verfügt der Objekttyp oder Basistyp eines Verpackungsobjekts von js über eine toString-Methode. Der von Object.prototype.toString() geerbte Aufruf gibt den String-Tag „[Objekttyp]“ des entsprechenden Typs zurück. Diese Methode ist wie ein zufälliger Schlag, um den Meister zu töten, und es fühlt sich an wie eine unbeabsichtigte Weidenpflanzung, die zu einem Weidenwald führt. Seine ursprüngliche Funktion besteht nur darin, eine Zeichenfolge abzurufen, die das Objekt darstellt. Jetzt wird es bei der JS-Typerkennung verwendet und seine Leistung ist sehr gut. Es funktioniert sehr gut für Basistypen und Objekttypen. Wenn wir auf einen Nachteil hinweisen müssen, können wir nur sagen, dass die zurückgegebene Zeichenfolge etwas kompliziert und nicht sehr bequem zu verwenden ist. Lassen Sie es uns jetzt vereinfachen. Schreiben Sie zuerst eine vereinfachte Version Funktion istTyp(Typ,Wert){ returniere Object.prototype.toString.call(Wert) === `[Objekt ${Typ}]` } Konsole.log(istTyp('Array',[])) console.log(istTyp('Nummer',1)) Dies ist nicht sehr praktisch in der Anwendung. Typparameter wie „Array“ und „Number“ können leicht falsch geschrieben werden. Daher ist zu hoffen, dass die Methode Parameter voreinstellen und eine Funktionsfabrik erstellen kann, um Funktionen wie „isArray“ aufzurufen und zurückzugeben. In der IDE verfügen Funktionsnamen über bessere Codehinweise als Zeichenfolgen und sind weniger anfällig für Rechtschreibfehler. Funktion istTyp(Typ){ Rückgabefunktion (Wert) { returniere Object.prototype.toString.call(Wert) === `[Objekt ${Typ}]` } } const isArray = isType('Array') const istNummer = istTyp('Nummer') console.log(istArray([]),istNummer(1)) Hier wird die Idee von Funktionen höherer Ordnung verwendet, Parameter beibehalten + eine neue Funktion zurückgeben. Man kann sich vorstellen, dass bind in js dies nicht nur binden, sondern auch Parameter beibehalten + eine neue Funktion zurückgeben kann, was auch hier geeignet ist. Funktion istTyp(Typ,Wert){ returniere Object.prototype.toString.call(Wert) === `[Objekt ${Typ}]` } const isArray = isType.bind(null,'Array') const isNumber = isType.bind(null,'Number') console.log(istArray([]),istNummer(1)) Wenn wir einen Schritt weiter gehen, können wir die Idee des Parameter-Curryings nutzen, um Funktion istTyp(Typ,Wert){ returniere Object.prototype.toString.call(Wert) === `[Objekt ${Typ}]` } Funktion aktuell (fn,...args1) { sei len = fn.length; Rückgabefunktion (...args2) { const args = args1.concat(args2); wenn (args.length < len) { gibt aktuell zurück (fn, ... args) }anders{ Rückgabewert fn(...args) } } } const isArray = aktuell(isType,'Array') const istNummer = aktuell(istTyp,'Nummer') console.log(istArray([]),istNummer(1)) Ergänzen Sie abschließend die unterstützten Typen und Sie sind fertig. Konstantentypen = [ 'Null', 'Undefiniert', 'Zeichenfolge', 'Nummer', 'Boolesch', 'Objekt', "Anordnung", 'Datum', 'Funktion', 'Regulärer Ausdruck', 'Symbol', 'Mathe', ] const checkTypeUtil = {} Typen.fürJeden((Typ)=>{ checkTypeUtil[`ist${Typ}`] = aktuell(istTyp,Typ) }) exportieren { checkTypeUtil } Konsole.log(checkTypeUtil.isArray([])) 5. Verwenden Sie Array.isArray, um das Array zu bestimmenWie oben erwähnt, kann instanceof zum Erkennen von Arrays verwendet werden. In der von iframe erstellten Umgebung mit mehreren Fenstern müssen Array und Array.prototype jedoch in jedem Fenster unterschiedlich sein, da die globale Fensterumgebung isoliert werden muss. Daher ist iframeA.Array.prototype ≠ iframeB.Array.prototype, sodass iframeA.arr instanceof iframeB.Array false zurückgeben muss. Dies ist ein Ereignis mit geringer Wahrscheinlichkeit, aber im Szenario der Verwendung von iframe ist es auch sehr wahrscheinlich, dass Werte aneinander übergeben werden. Bei der Verwendung von Array.isArray, das von ES6 bereitgestellt wird, tritt dieses Problem nicht auf und das Array kann genau beurteilt werden. So kannst du pollen wenn (!Array.isArray) { Array.isArray = Funktion(x) { returniere Object.prototype.toString.call(x) === '[Objekt-Array]'; }; } 6. Unterscheiden Sie zwischen ArrayLike und ArrayDie Definition der Array-Klasse lautet:
Funktion ist wie Array (x) { wenn(!(Typ von x === 'Objekt' && x !== null)){ return false } Rückgabetyp von x.length === 'Zahl' und x.length >= 0 und !Array.isArray(x) } Array-ähnliche Objekte können mit Array.from Array.prototype.slice.call(val) in echte Arrays umgewandelt werden. 7. Bestimmen Sie, ob ein Objekt ein reines Objekt (oder ein gewöhnliches Objekt) istDefinition eines reinen Objekts: bezieht sich speziell auf Objekte, die auf die folgenden drei Arten erstellt wurden
Die jQuery- und Lodash-Quellcodes werden mit der folgenden Methode erkannt const funcToString = Funktion.prototype.toString const objectCtorString = funcToString.call(Object) Funktion isPlainObject(Wert){ // Verwenden Sie toString, um zuerst andere Datentypen auszuschließen if(!value || !Object.prototype.toString.call(value) === "[object Object]"){ return false } const proto = Object.getPrototypeOf(Wert) if(proto === null){//Kompatibel mit Object.create(null) return true } const Ctor = Object.prototype.hasOwnProperty.call(proto,'Konstruktor') && proto.Konstruktor; wenn(Typ von Ctor !== 'Funktion'){ return false } // Hier verwenden wir den String, um zu bestimmen, ob der Konstruktor ein Objekt ist, anstatt direkt instanceof zu verwenden, um das oben erwähnte Problem unterschiedlicher Objekte in mehreren Fensterumgebungen zu vermeiden if(funcToString.call(Ctor) === objectCtorString){ returniere wahr } return false } Konsole.log(isPlainObject(Objekt.erstellen(null))) console.log(isPlainObject(neues Objekt)) console.log(isPlainObject({a:1})) 8. Wie erkennt man NaN? Was ist der Unterschied zwischen Number.isNaN und isNaN?Fazit: Number.isNaN prüft streng, ob der übergebene Wert direkt gleich NaN ist. isNaN führt zuerst eine Number()-Konvertierung durch und ermittelt dann, ob es NaN ist. 9. EntentypisierungTatsächlich ist die obige Verwendung des Konstruktors zur Bestimmung des Datentyps die Verwendung dieser Methode. Um zu bestimmen, ob es sich bei einem Tier um eine Ente handelt, können wir eine grobe Einschätzung auf Grundlage einfacher empirischer Beurteilungen vornehmen, etwa ob es wie eine Ente aussieht und wie eine Ente quakt. Um beispielsweise festzustellen, ob ein Objekt ein Promise ist, können Sie Folgendes tun: Funktion istPromise(x){ if (!(x Instanz von Promise)) { return false } Rückgabetyp von x.then === 'Funktion' } ZusammenfassenDies ist das Ende dieses Artikels zur JS-Datentyperkennung. Weitere relevante Inhalte zur JS-Datentyperkennung finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Ausführliche Erläuterung der Konzepte und Verwendung von MySQL-Transaktionen
>>: Bringen Sie Ihnen bei, wie Sie Hive3.1.2 auf Tencent Cloud erstellen
Vorwort Mit der Funktion count werden die Datensä...
Dieser Artikel installiert die Google-Eingabemeth...
Inhaltsverzeichnis Methode 1: Rufen Sie die Funkt...
<br />Zu jedem unserer Themen bespricht das ...
[LeetCode] 182.Doppelte E-Mails Schreiben Sie ein...
Als ich zum ersten Mal mit HTML in Berührung kam,...
flexibles Layout Definition: Das Element des Flex...
Ich werde meinen ersten Versuch mit vue3.0 aufzei...
Im MySQL-Betrieb und bei der Wartung möchte ein F...
Inhaltsverzeichnis 1. Übersicht 1.1 Definition 1....
Vorwort Kürzlich wurde ich in einem Interview gef...
Die default_server-Direktive von nginx kann einen...
Bei der Installation des Quellcodes von CentOS6.9...
So schreiben Sie ein Vue-foreach-Array und durchl...
Umfeld Hostname IP-Adresse Aufschlag Jenkins 192....