Mit JavaScript können wir mit Grundelementen (Zeichenfolgen, Zahlen usw.) arbeiten, als wären sie Objekte. Sie stellen auch Methoden bereit, die als solche aufgerufen werden können. Wir werden diese bald untersuchen, aber zuerst werden wir sehen, wie es funktioniert, denn natürlich sind Grundelemente keine Objekte (und hier werden wir es noch klarer machen).
Schauen wir uns die wichtigsten Unterschiede zwischen Grundelementen und Objekten an.
Ein Primitiv
Ist ein Wert eines primitiven Typs.
Es gibt 7 primitive Typen: string
, number
, bigint
, boolean
, symbol
, null
und undefined
.
Ein Objekt
Kann mehrere Werte als Eigenschaften speichern.
Kann mit {}
erstellt werden, zum Beispiel: {name: "John", age: 30}
. Es gibt noch andere Arten von Objekten in JavaScript: Funktionen sind beispielsweise Objekte.
Das Beste an Objekten ist, dass wir eine Funktion als eine ihrer Eigenschaften speichern können.
lass John = { Name: „John“, sayHi: function() { alarm("Hallo Kumpel!"); } }; john.sayHi(); // Hallo Kumpel!
Hier haben wir also ein Objekt john
mit der Methode sayHi
erstellt.
Es gibt bereits viele integrierte Objekte, beispielsweise solche, die mit Datumsangaben, Fehlern, HTML-Elementen usw. arbeiten. Sie verfügen über unterschiedliche Eigenschaften und Methoden.
Diese Funktionen sind jedoch mit Kosten verbunden!
Objekte sind „schwerer“ als Grundelemente. Sie benötigen zusätzliche Ressourcen zur Unterstützung der internen Maschinerie.
Hier ist das Paradoxon, mit dem der Entwickler von JavaScript konfrontiert ist:
Es gibt viele Dinge, die man mit einem Grundelement tun möchte, wie zum Beispiel einer Zeichenfolge oder einer Zahl. Es wäre großartig, mithilfe von Methoden darauf zuzugreifen.
Primitive müssen so schnell und leicht wie möglich sein.
Die Lösung sieht etwas umständlich aus, aber hier ist sie:
Primitive sind immer noch primitiv. Ein einzelner Wert, wie gewünscht.
Die Sprache ermöglicht den Zugriff auf Methoden und Eigenschaften von Zeichenfolgen, Zahlen, booleschen Werten und Symbolen.
Damit das funktioniert, wird ein spezieller „Objekt-Wrapper“ erstellt, der die zusätzliche Funktionalität bereitstellt, und dann zerstört.
Die „Objekt-Wrapper“ sind für jeden primitiven Typ unterschiedlich und heißen: String
, Number
, Boolean
, Symbol
und BigInt
. Daher stellen sie unterschiedliche Methodensätze zur Verfügung.
Beispielsweise gibt es eine String-Methode str.toUpperCase(), die einen großgeschriebenen str
zurückgibt.
So funktioniert es:
let str = "Hallo"; alarm( str.toUpperCase() ); // HALLO
Ganz einfach, oder? Folgendes passiert tatsächlich in str.toUpperCase()
:
Der String str
ist ein Grundelement. Sobald also auf seine Eigenschaft zugegriffen wird, wird ein spezielles Objekt erstellt, das den Wert der Zeichenfolge kennt und über nützliche Methoden wie toUpperCase()
verfügt.
Diese Methode wird ausgeführt und gibt eine neue Zeichenfolge zurück (angezeigt durch alert
).
Das spezielle Objekt wird zerstört und der primitive str
bleibt in Ruhe.
Primitiven können also Methoden bereitstellen, bleiben aber dennoch leichtgewichtig.
Die JavaScript-Engine optimiert diesen Prozess erheblich. Möglicherweise wird sogar die Erstellung des zusätzlichen Objekts überhaupt übersprungen. Aber es muss sich trotzdem an die Spezifikation halten und sich so verhalten, als würde es eine solche erstellen.
Eine Zahl hat eigene Methoden, zum Beispiel rundet toFixed(n) die Zahl auf die angegebene Genauigkeit:
sei n = 1,23456; alarm( n.toFixed(2) ); // 1.23
Spezifischere Methoden werden wir in den Kapiteln „Zahlen“ und „Strings“ sehen.
Die Konstruktoren String/Number/Boolean
sind nur für den internen Gebrauch bestimmt
Einige Sprachen wie Java ermöglichen es uns, explizit „Wrapper-Objekte“ für Grundelemente zu erstellen, indem wir eine Syntax wie new Number(1)
oder new Boolean(false)
verwenden.
In JavaScript ist das aus historischen Gründen auch möglich, aber dringend nicht zu empfehlen . An mehreren Stellen wird es verrückt spielen.
Zum Beispiel:
alarm( typeof 0 ); // "Nummer" alarm( typeof new Number(0) ); // "Objekt"!
Objekte sind in if
immer wahr, daher wird hier die Warnung angezeigt:
sei null = neue Zahl(0); if (zero) { // null ist wahr, weil es ein Objekt ist alarm( "Null ist wahr!?!" ); }
Andererseits ist die Verwendung derselben Funktionen String/Number/Boolean
ohne new
völlig in Ordnung und nützlich. Sie konvertieren einen Wert in den entsprechenden Typ: in eine Zeichenfolge, eine Zahl oder einen booleschen Wert (primitiv).
Dies ist zum Beispiel völlig gültig:
let num = Number("123"); // einen String in eine Zahl umwandeln
null/undefiniert haben keine Methoden
Ausnahmen sind die speziellen Grundelemente null
und undefined
. Sie haben keine entsprechenden „Wrapper-Objekte“ und stellen keine Methoden bereit. In gewissem Sinne sind sie „die primitivsten“.
Ein Versuch, auf eine Eigenschaft mit einem solchen Wert zuzugreifen, würde den folgenden Fehler ergeben:
alarm(null.test); // Fehler
Primitive außer null
und undefined
bieten viele hilfreiche Methoden. Wir werden diese in den kommenden Kapiteln untersuchen.
Formal funktionieren diese Methoden über temporäre Objekte, aber JavaScript-Engines sind gut darauf abgestimmt, dies intern zu optimieren, sodass der Aufruf nicht teuer ist.
Wichtigkeit: 5
Betrachten Sie den folgenden Code:
let str = "Hallo"; str.test = 5; alarm(str.test);
Was denkst du, wird es funktionieren? Was wird gezeigt?
Versuchen Sie es auszuführen:
let str = "Hallo"; str.test = 5; // (*) alarm(str.test);
Je nachdem, ob Sie use strict
oder nicht, kann das Ergebnis wie folgt aussehen:
undefined
(kein strikter Modus)
Ein Fehler (strenger Modus).
Warum? Lassen Sie uns noch einmal abspielen, was in Zeile (*)
passiert:
Wenn auf eine Eigenschaft von str
zugegriffen wird, wird ein „Wrapper-Objekt“ erstellt.
Im strikten Modus ist das Schreiben darin ein Fehler.
Andernfalls wird die Operation mit der Eigenschaft fortgesetzt, das Objekt erhält die test
, aber danach verschwindet das „Wrapper-Objekt“, sodass in der letzten Zeile str
keine Spur der Eigenschaft vorhanden ist.
Dieses Beispiel zeigt deutlich, dass Grundelemente keine Objekte sind.
Sie können keine zusätzlichen Daten speichern.