Eine detaillierte Einführung in primitive Werte und Wrapper-Objekte in JavaScript

Eine detaillierte Einführung in primitive Werte und Wrapper-Objekte in JavaScript

Vorwort

Da JavaScript immer beliebter wird, beginnen sich immer mehr Entwickler mit JavaScript auseinanderzusetzen und es zu verwenden.

Gleichzeitig habe ich festgestellt, dass viele Entwickler kein klares Verständnis der grundlegendsten primitiven Werte und Paketobjekte in JavaScript haben.

Deshalb stellt Zhapi sie Ihnen in diesem Artikel im Detail vor.

🧐 Und nun los geht’s!

Text

Primitive Typen

Primitive Typen werden auch „Basistypen“ genannt.

Derzeit gibt es in JavaScript die folgenden primitiven Typen:

  • Schnur
  • Nummer
  • Boolescher Wert
  • Null
  • undefiniert
  • bigint (große Ganzzahl, ES6)
  • Symbol

📝 Wie folgt:

Typ von 'chenpipi'; // "Zeichenfolge"
Typ von 12345; // "Zahl"
Typ von true; // "Boolesch"
Typ von null; // "Objekt"
Typ von nicht definiert; // "nicht definiert"
Typ von 12345n; // "bigint"
Typ von Symbol(); // "Symbol"

💡 Besondere Aufmerksamkeit

Obwohl typeof null „Objekt“ zurückgibt, bedeutet dies nicht, dass null ein Objekt ist. Dies ist eigentlich ein Fehler in JavaScript und ist seit der Geburt von JavaScript so.

In der ursprünglichen Implementierung von JavaScript wurden Werte in JavaScript durch ein Tag dargestellt, das den Typ und den tatsächlichen Datenwert angab. Der Typ-Tag eines Objekts ist 0. Da „null“ einen Nullzeiger darstellt (auf den meisten Plattformen den Wert 0x00), ist der Typtag von „null“ 0 und „typeof null“ gibt daher „Objekt“ zurück.

Die Geschichte von „typeof null“: https://2ality.com/2013/10/typeof-null.html

Primitive Werte

Primitive Werte sind Werte (Daten) primitiver Typen.

Ein primitiver Wert sind Daten, die kein Objekt sind und keine Methoden haben.

Ein primitiver Wert sind Nicht-Objektdaten, die über keine Methoden verfügen.

Das heißt, primitive Werte wie Zeichenfolgen, Zahlen und Boolesche Werte haben keine Eigenschaften oder Methoden.

😨 Haben die Freunde mit dem ausgeprägten Geruchssinn zu diesem Zeitpunkt bereits bemerkt, dass etwas nicht stimmt?

Es ist Kreuzkümmel! Ich habe Kreuzkümmel hinzugefügt! (Den Hundekopf manuell durchstreichen)

🤓 Hier gibt es einen sehr interessanten Punkt, aber bevor wir dieses Problem diskutieren, wollen wir zunächst das Verpackungsobjekt verstehen.

Wrapper-Objekte

Alle primitiven Typen außer null und undefined haben ihre entsprechenden Wrapper-Objekte:

  • Zeichenfolge
  • Nummer
  • Boolescher Wert
  • BigInt (ES6)
  • Symbol (Flagge? ES6)

Objekt

Objekt ist ein Referenztyp.

Erstens ist das Wrapper-Objekt selbst ein Objekt und auch eine Funktion.

String-Instanz von Object; // wahr
String-Instanz der Funktion; // wahr

Konstruktor

Beispiel

String, Number und Boolean unterstützen alle die Verwendung des neuen Operators zum Erstellen entsprechender Verpackungsobjektinstanzen.

📝 Beispielsweise die Deklaration von String (Auszug):

Schnittstelle StringConstructor {
  neu(Wert?: beliebig): Zeichenfolge;
  (Wert?: beliebig): Zeichenfolge;
  schreibgeschützter Prototyp: String;
}
Deklarieren Sie var String: StringConstructor;

📝 Die mit dem neuen Operator erhaltenen Daten sind ein Objekt:

// Zeichenfolgetyp von „pp“; // "Zeichenfolge"
Typ von neuer String('pp'); // "Objekt"
neue String()-Instanz von Object; // wahr
// Nummer Typ von 123; // "Nummer"
Typ der neuen Zahl (123); // "Objekt"
neue Number()-Instanz von Object; // wahr
// Boolescher Typ von true; // "Boolesch"
Typ von neuem Boolean (true); // "Objekt"
neue Boolean()-Instanz von Object; // wahr

📝 Wir können die Funktion valueOf() der gewrappten Objektinstanz aufrufen, um ihren ursprünglichen Wert abzurufen:

// Zeichenfolge let s = neuer String('pp');
s.valueOf(); // "pp"
typeof s.valueOf(); // "Zeichenfolge"
// Zahl let n = neue Zahl(123);
n.WertVon(); // 123
typeof n.valueOf(); // "Zahl"
// Boolesch let b = neuer Boolescher Wert(true);
b.valueOf(); // wahr
Typ von b.valueOf(); // "Boolesch"

„Ausreißer“ (Achtung)

BigInt und Symbol sind beide „unvollständige Klassen“ und unterstützen den neuen Operator nicht.

📝 Beispielsweise die Deklaration von BigInt (Auszug):

Schnittstelle BigIntConstructor {
  (Wert?: beliebig): bigint;
  schreibgeschützter Prototyp: BigInt;
}
Deklarieren Sie var BigInt: BigIntConstructor;

Sie können sehen, dass in der BigInt-Deklaration keine neue Operatorfunktion vorhanden ist.

Gewöhnliche Funktion (Funktion)

Wrapper-Objekte können auch als normale Funktionen verwendet werden.

Mit den Funktionen String(), Number() und Boolean() können explizite Typkonvertierungen für beliebige Datentypen durchgeführt werden.

Darüber hinaus kann die Funktion Object() auch zur expliziten Typkonvertierung verwendet werden, worauf in diesem Artikel jedoch nicht näher eingegangen wird.

Zeichenfolge

📝 Beispielcode:

typeof String(); // "Zeichenfolge"
Zeichenfolge(); // ""
Zeichenfolge('pp'); // "pp"
Zeichenfolge(123); // "123"
String(true); // "wahr"
String(falsch); // "falsch"
String(null); // "null"
String(undefiniert); // "undefiniert"
Zeichenfolge([]); // ""
String({}); // "[Objekt Objekt]"

💡 Tipp 1

Wenn wir die Funktion String() verwenden, um ein Objekt zu konvertieren, greift JavaScript zuerst auf die Funktion toString() des Objekts zu. Wenn sie nicht implementiert ist, durchsucht es die Prototypenkette.

🌰 Beispiel: Die Ausführung von String({ toString() { return 'pp'; } }) gibt „pp“ zurück, nicht „[object Object]“.

Daher kann die Funktion String() nicht verwendet werden, um zu bestimmen, ob ein Wert ein Objekt ist (dies schlägt fehl).

💡 Tipp 2

Die allgemein verwendete Methode zur Beurteilung des Objekts ist Object.prototype.toString({}) === '[object Object]'.

🌰 Beispiel: Die Ausführung von Object.prototype.toString({ toString() { return 'pp'; } }) gibt „[object Object]“ zurück.

Nummer

📝 Beispielcode:

Typ von Nummer(); // "Nummer"
Zahl(); // 0
Zahl(''); // 0
Zahl('pp'); // NaN
Zahl(123); // 123
Zahl (wahr); // 1
Zahl (falsch); // 0
Zahl(null); // 0
Zahl (undefiniert); // NaN
Zahl([]); // 0
Zahl({}); // NaN

💡 Tipps

Für die Funktion Number() ist die nützlichste Konvertierung wahrscheinlich die Umwandlung von true und false in 1 und 0.

Boolescher Wert

📝 Beispielcode:

Typ von Boolean(); // "Boolesch"
Boolean(); // falsch
Boolean(''); // falsch
Boolean('pp'); // wahr
Boolean(0); // falsch
Boolean(1); // wahr
Boolean(null); // falsch
Boolean (undefiniert); // falsch
Boolean([]); // wahr
Boolean({}); // wahr

💡 Tipps

In einigen Fällen verwenden wir 0 und 1 in den Daten, um wahre und falsche Zustände darzustellen. In diesem Fall können wir Boolean() verwenden, um den Zustand zu bestimmen.

BigInt

Die Funktion BigInt() wird verwendet, um eine Ganzzahl in eine große Ganzzahl umzuwandeln.

Diese Funktion akzeptiert eine Ganzzahl als Parameter. Wenn der übergebene Parameter eine Gleitkommazahl oder ein anderer nicht numerischer Datentyp ist, wird ein Fehler gemeldet.

📝 Beispielcode:

BigInt(123); // 123n
BigInt(123n); // 123n
Typ von 123n; // "bigint"
Typ von BigInt (123); // "bigint"

BigInt und Zahl

Es ist zu beachten, dass BigInt und Number nicht genau gleich sind (nur ungefähr gleich).

📝 Beispielcode:

123n === 123; // falsch
123n == 123; // wahr

Symbol

Mit der Funktion Symbol() wird ein Wert vom Typ Symbol erstellt.

Diese Funktion akzeptiert eine Zeichenfolge als Deskriptor (Parameter). Wenn ein Wert eines anderen Typs übergeben wird, wird dieser in eine Zeichenfolge konvertiert (außer undefined).

Beachten Sie, dass jeder Symbolwert eindeutig ist, auch wenn die Deskriptoren gleich sind.

Und Symboltypdaten können nur durch die Funktion Symbol() erstellt werden.

📝 Beispielcode:

// Der unten stehende Rückgabewert wird von Devtools simuliert, nicht der tatsächliche Wert Symbol('pp'); // Symbol(pp)
Symbol(123); // Symbol(123)
Symbol(null); // Symbol(null)
Symbol({}); // Symbol([Objekt Objekt])

// TypTyp von Symbol('pp'); // "Symbol"
Symbol('pp') === Symbol('pp'); // falsch

// Deskriptor Symbol('pp').description; // "pp"
Symbol(123).Beschreibung; // "123"
Symbol({}).description; // "[Objekt Objekt]"
Symbol().description; // undefiniert
Symbol(undefiniert).Beschreibung; // undefiniert

Primitiv, kein Objekt

🎃 Der interessante Teil kommt~

Keine Eigenschaften, keine Funktionen

Zu Beginn dieses Artikels wurde erwähnt, dass „ein primitiver Wert ein Nicht-Objekt-Datenwert ist, der über keine Methoden verfügt.“

Wir alle wissen, dass Objekte Eigenschaften und Methoden haben können.

Da es sich bei Zeichenfolgen jedoch nicht um Objekte handelt, können ihnen keine Eigenschaften hinzugefügt werden.

📝 Machen Sie ein kleines Experiment:

sei a = "chenpipi";
console.log(a.Länge); // 8
// Versuchen Sie, ein neues Attribut hinzuzufügen a.name = 'Danzu Wu';
console.log(a.name); // undefiniert
// Versuchen Sie, einen vorhandenen Eigenschaftstyp von a.slice zu ändern. // "Funktion"
a.Scheibe = null;
Typ von a.slice; // "Funktion"

🎬 Kleines Zhapi-Theater

Zu diesem Zeitpunkt nutzte ein sturer Freund seine Widerlegungskunst.

Du Trottel, hör auf, die Leute hier zu verarschen. Wenn ich normalerweise Bugs oder keinen Code schreibe, kann ich offensichtlich Methoden für Zeichenfolgen, Zahlen und Boolesche Werte aufrufen!

📝 Beispielsweise kann der folgende Code normal ausgeführt werden und die erwarteten Ergebnisse erhalten:

// Zeichenfolge let s = "chenpipi";
s.toUpperCase(); // "CHENPIPI"
'ChenPiPi'.slice(4); // "PiPi"
// Zahl sei n = 123;
n.toString(); // "123"
(123.45).toFixed(2); // "123.5"
// Boolescher Wert let b = true;
b.toString(); // "wahr"
false.toString(); // "falsch"

💡 Nutzloses Wissen

Ist Ihnen aufgefallen, dass eine Funktion nicht direkt nach einem numerischen Literal aufgerufen werden kann? Beispielsweise wird bei der Ausführung von 123.toString() ein SyntaxError (Syntaxfehler) gemeldet.

Dies liegt daran, dass Zahlen (Gleitkommazahlen) selbst Dezimalpunkte verwenden und auch das Aufrufen von Funktionen einen Dezimalpunkt erfordert, was zu Mehrdeutigkeiten führt (Zeichenfolgen und Boolesche Werte haben dieses Problem nicht).

In diesem Fall können wir Klammern () verwenden, um die Zahl zu umschließen, z. B. (123).toString(); oder zwei aufeinanderfolgende Dezimalstellen verwenden, um die Funktion aufzurufen, z. B. 123..toString().

🤔 Das ist komisch

Da Zeichenfolgen keine Objekte sind, warum haben Zeichenfolgen dann Attribute und Methoden?

Bei näherem Überlegen sind Zahlen einfach nur Zahlen. Wie können in Zahlen irgendwelche Methoden stecken?

Das ist zwar unlogisch, widerspricht aber auch der Realität.

Was ist los? ? ?

Stand User (Ich kann das nicht übersetzen)

Die Antwort ist enthüllt~

😎 Im Geheimen operieren

Nehmen wir als Beispiel einen String. Wenn wir die Eigenschaften oder Methoden eines Strings im Code lesen, führt JavaScript im Hintergrund die folgenden Operationen aus:

  1. Erstellen Sie eine temporäre Wrapper-Objektinstanz mit „new String()“.
  2. Führen Sie unsere Code-Logik durch das erstellte Objekt aus (lesen Sie Eigenschaften oder führen Sie Funktionen aus).
  3. Temporäre Objekte werden nicht mehr verwendet und können vernichtet werden.

📝 Zum Beispiel:

sei a = "chenpipi";
console.log(a); // "chenpipi"
// ------------------------------
sei b1 = a.Länge;
konsole.log(b1); // 8
// Der obige Code entspricht:
sei b2 = (neuer String(a)).Länge;
konsole.log(b2); // 8
// ------------------------------
sei c1 = a.toUpperCase();
console.log(c1); // "CHENPIPI"
// Der obige Code entspricht:
sei c2 = (neuer String(a)).toUpperCase();
console.log(c2); // "CHENPIPI"

Dasselbe gilt für Zahlen und Boolesche Werte, allerdings werden Zahlen mit „new Number()“ erstellt, während Boolesche Werte mit „new Boolean()“ erstellt werden.

📝 Zusätzlich zu den obigen Beispielen ist der stärkste Beweis ihr Konstruktor:

'chenpipi'.Konstruktor === String; // wahr
(12345).constructor === Zahl; // wahr
true.constructor === Boolean; // wahr

Dies alles wird im Dunkeln durch JavaScript erledigt und die dabei generierten temporären Objekte sind nur einmalig (werden nach der Verwendung weggeworfen).

😮 Ich verstehe

Juhu, jetzt ergibt es Sinn!

Dies erklärt auch, warum wir auf Eigenschaften und Methoden von Zeichenfolgen zugreifen, aber keine Eigenschaften hinzufügen oder ändern können.

Das liegt daran, dass das Ziel, auf das wir tatsächlich zugreifen, das von JavaScript erstellte temporäre Objekt ist und nicht die Zeichenfolge selbst!

Unsere Additions- oder Änderungsoperation ist also tatsächlich wirksam, allerdings nur bei einem temporären Objekt!

📝 Gefällt mir:

// Im Code:
sei a = "chenpipi";
a.name = "Daniel Wu";
console.log(a.name); // undefiniert

// entspricht:
sei a = "chenpipi";
(neuer String(a)).name = "Daniel Wu";
console.log(a.name); // undefiniert

// entspricht:
sei a = "chenpipi";
: Lassen Sie temp = neuer String(a);
temp.name = "Daniel Wu";
console.log(a.name); // undefiniert

Zusammenfassung

🎉 Das Obige ist der vollständige Inhalt dieses Artikels.

Lassen Sie uns abschließend zusammenfassen:

  1. Die meisten primitiven Typen haben entsprechende Wrapper-Objekte;
  2. Einige Wrapper-Objekte können neu sein, andere nicht.
  3. Wrapper-Objekte werden im Allgemeinen zur expliziten Typkonvertierung verwendet.
  4. Es gibt Eigenschaften und Methoden für Objekte.
  5. Es gibt keine Eigenschaften oder Methoden für primitive Werte.
  6. Primitive Werte können auch keine Eigenschaften oder Methoden haben;
  7. Aber wir können primitive Werte wie Objekte manipulieren;
  8. Dies liegt daran, dass JavaScript bei der Codeausführung etwas Hinterhältiges tut;
  9. JavaScript verwendet temporäre Wrapper-Objekte, um Operationen an primitiven Werten durchzuführen.

Normalerweise achten wir beim Schreiben von Code nicht darauf und tatsächlich hat es keinen Einfluss auf das Schreiben unseres Codes.

Ist dieser Artikel also nicht Zeitverschwendung?

🙉 Ja, aber nicht ganz~

Kenne dich selbst und kenne deinen Feind, und du wirst jede Schlacht gewinnen.

Nachdem Sie sich dieses nutzlose kleine Wissen angeeignet haben, können Sie JavaScript besser verstehen. Zumindest können Sie damit angeben (Hundekopf~).

Ressourcen zum Thema

Fortgeschrittene JavaScript-Programmierung (4. Auflage)

JavaScript: Das ultimative Handbuch (6. Auflage)

Primitiv – MDN: https://developer.mozilla.org/en-US/docs/Glossary/Primitive

Die Geschichte von „typeof null“: https://2ality.com/2013/10/typeof-null.html

Dies ist das Ende dieses Artikels über JavaScript-Grundwerte und Wrapper-Objekte. Weitere relevante Inhalte zu JS-Grundwerten und Wrapper-Objekten finden Sie in früheren Artikeln auf 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:
  • Analyse von JavaScript-Grundwerten und Objektreferenzbeispielen
  • Einführung in integrierte JavaScript-Objekte
  • JavaScript-Grundlagenobjekte
  • Detaillierte Erläuterung der Konvertierung von JavaScript-Objekten in primitive Werte

<<:  So fügen Sie Docker dynamisch Ports hinzu, ohne das Image neu zu erstellen

>>:  Grafisches Tutorial zur Installation und Konfiguration der komprimierten Version von MySQL 8.0.11

Artikel empfehlen

React Native realisiert den Auf- und Ab-Pull-Effekt der Überwachungsgeste

React Native implementiert die Überwachungsgeste ...

Mysql 5.6.37 Winx64-Installation Dual-Version MySQL-Hinweise

Wenn MySQL Version 5.0 bereits auf dem Computer v...

MySQL-Daemon konnte nicht gestartet werden – Fehlerlösung

MySQL-Daemon konnte nicht gestartet werden – Fehl...

Wofür wird jQuery verwendet? jQuery ist eigentlich ein js-Framework

Einführung in jQuery Die jQuery-Bibliothek kann e...

Rastersysteme im Webdesign

Bildung des Gittersystems Im Jahr 1692 war der fr...

Docker-Konfiguration Alibaba Cloud Image Acceleration Pull-Implementierung

Heute habe ich Docker verwendet, um das Image abz...

6 Möglichkeiten, die von Linux-Prozessen belegten Portnummern anzuzeigen

Für Linux-Systemadministratoren ist es von entsch...

Verwendung des Linux-Befehls passwd

1. Befehlseinführung Mit dem Befehl passwd werden...

Detaillierte Erklärung des Json-Formats

Inhaltsverzeichnis Ein JSON basiert auf zwei Stru...