Eine neue Ergänzung
Dies ist eine neue Ergänzung der Sprache. Alte Browser benötigen möglicherweise Polyfills.
Die optionale Verkettung ?.
ist eine sichere Möglichkeit, auf verschachtelte Objekteigenschaften zuzugreifen, auch wenn keine Zwischeneigenschaft vorhanden ist.
Wenn Sie gerade erst begonnen haben, das Tutorial zu lesen und JavaScript zu lernen, ist das Problem vielleicht noch nicht aufgetreten, aber es kommt recht häufig vor.
Nehmen wir als Beispiel an, wir haben user
, die die Informationen über unsere Benutzer enthalten.
Die meisten unserer Benutzer haben Adressen in der Eigenschaft user.address
mit der Straße user.address.street
, aber einige haben sie nicht angegeben.
Wenn wir in einem solchen Fall versuchen, user.address.street
abzurufen und der Benutzer zufällig keine Adresse hat, erhalten wir eine Fehlermeldung:
let user = {}; // ein Benutzer ohne „address“-Eigenschaft alarm(user.address.street); // Fehler!
Das ist das erwartete Ergebnis. JavaScript funktioniert so. Da user.address
undefined
ist, schlägt der Versuch, user.address.street
abzurufen, mit einem Fehler fehl.
In vielen praktischen Fällen würden wir hier lieber undefined
als einen Fehler erhalten (was „keine Straße“ bedeutet).
…und noch ein Beispiel. In der Webentwicklung können wir mit einem speziellen Methodenaufruf wie document.querySelector('.elem')
ein Objekt abrufen, das einem Webseitenelement entspricht, und es gibt null
zurück, wenn kein solches Element vorhanden ist.
// document.querySelector('.elem') ist null, wenn kein Element vorhanden ist let html = document.querySelector('.elem').innerHTML; // Fehler, wenn es null ist
Auch hier gilt: Wenn das Element nicht vorhanden ist, erhalten wir beim Zugriff auf die .innerHTML
Eigenschaft von null
eine Fehlermeldung. Und in manchen Fällen, wenn das Fehlen des Elements normal ist, möchten wir den Fehler vermeiden und einfach html = null
als Ergebnis akzeptieren.
Wie können wir das machen?
Die offensichtliche Lösung wäre, den Wert mit if
oder dem Bedingungsoperator ?
zu überprüfen. , bevor Sie auf seine Eigenschaft zugreifen, wie folgt:
let user = {}; alarm(user.address ? user.address.street : undefiniert);
Es funktioniert, es gibt keinen Fehler ... Aber es ist ziemlich unelegant. Wie Sie sehen können, erscheint "user.address"
zweimal im Code.
So würde dasselbe für document.querySelector
aussehen:
let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
Wir können sehen, dass die Elementsuche document.querySelector('.elem')
hier tatsächlich zweimal aufgerufen wird. Nicht gut.
Bei tiefer verschachtelten Eigenschaften wird es noch hässlicher, da mehr Wiederholungen erforderlich sind.
Lassen Sie uns beispielsweise user.address.street.name
auf ähnliche Weise ermitteln.
let user = {}; // Benutzer hat keine Adresse warning(user.address ? user.address.street ? user.address.street.name : null : null);
Das ist einfach schrecklich, man kann sogar Probleme haben, solchen Code zu verstehen.
Es gibt eine etwas bessere Möglichkeit, es mit dem &&
Operator zu schreiben:
let user = {}; // Benutzer hat keine Adresse Alert( user.address && user.address.street && user.address.street.name ); // undefiniert (kein Fehler)
Durch UND-Verknüpfung des gesamten Pfads zur Eigenschaft wird sichergestellt, dass alle Komponenten vorhanden sind (andernfalls wird die Auswertung gestoppt), aber das ist auch nicht ideal.
Wie Sie sehen, werden Eigenschaftsnamen im Code immer noch dupliziert. Im obigen Code kommt user.address
beispielsweise dreimal vor.
Deshalb die optionale Verkettung ?.
wurde der Sprache hinzugefügt. Um dieses Problem ein für alle Mal zu lösen!
Die optionale Verkettung ?.
Stoppt die Auswertung, wenn der Wert vor ?.
ist undefined
oder null
und gibt undefined
zurück.
Im weiteren Verlauf dieses Artikels sagen wir der Kürze halber, dass etwas „existiert“, wenn es nicht null
und nicht undefined
ist.
Mit anderen Worten, value?.prop
:
Funktioniert als value.prop
, wenn value
vorhanden ist,
andernfalls (wenn value
undefined/null
ist) wird undefined
zurückgegeben.
Hier ist der sichere Weg, mit ? auf user.address.street
zuzugreifen ?.
:
let user = {}; // Benutzer hat keine Adresse alarm( user?.address?.street ); // undefiniert (kein Fehler)
Der Code ist kurz und klar, es gibt keinerlei Duplikate.
Hier ist ein Beispiel mit document.querySelector
:
let html = document.querySelector('.elem')?.innerHTML; // ist undefiniert, wenn kein Element vorhanden ist
Das Lesen der Adresse mit user?.address
funktioniert auch, wenn user
nicht vorhanden ist:
let user = null; alarm( user?.address ); // undefiniert alarm( user?.address.street ); // undefiniert
Bitte beachten Sie: das ?.
Die Syntax macht den Wert davor optional, aber nicht weiter.
ZB in user?.address.street.name
das ?.
Ermöglicht user
sicher null/undefined
zu sein (und gibt in diesem Fall undefined
zurück), aber das gilt nur für user
. Auf weitere Eigenschaften wird regelmäßig zugegriffen. Wenn wir möchten, dass einige davon optional sind, müssen wir weitere ersetzen .
mit ?.
.
Überbeanspruchen Sie die optionale Verkettung nicht
Wir sollten ?.
nur dort, wo es in Ordnung ist, dass etwas nicht existiert.
Wenn beispielsweise gemäß unserer Codelogik ein user
vorhanden sein muss, address
jedoch optional ist, sollten wir user.address?.street
schreiben, aber nicht user?.address?.street
.
Wenn user
dann nicht definiert ist, sehen wir einen Programmierfehler und beheben ihn. Ansonsten, wenn wir es überbeanspruchen ?.
, Codierungsfehler können an ungeeigneten Stellen unterdrückt werden und das Debuggen wird schwieriger.
Die Variable vor ?.
müssen deklariert werden
Wenn überhaupt keine Variable user
vorhanden ist, löst user?.anything
einen Fehler aus:
// ReferenceError: Benutzer ist nicht definiert Benutzer?.Adresse;
Die Variable muss deklariert werden (z. B. let/const/var user
oder als Funktionsparameter). Die optionale Verkettung funktioniert nur für deklarierte Variablen.
Wie bereits gesagt, das ?.
stoppt die Auswertung sofort („kurzschließt“), wenn der linke Teil nicht existiert.
Wenn sich also rechts von ?.
, sie werden nicht gemacht.
Zum Beispiel:
let user = null; sei x = 0; user?.sayHi(x++); // kein „Benutzer“, daher erreicht die Ausführung den sayHi-Aufruf und x++ nicht alarm(x); // 0, Wert nicht erhöht
Die optionale Verkettung ?.
ist kein Operator, sondern ein spezielles Syntaxkonstrukt, das auch mit Funktionen und eckigen Klammern funktioniert.
Beispielsweise wird ?.()
verwendet, um eine Funktion aufzurufen, die möglicherweise nicht existiert.
Im folgenden Code verfügen einige unserer Benutzer über admin
Methode, andere nicht:
let userAdmin = { admin() { Alert("Ich bin Administrator"); } }; let userGuest = {}; userAdmin.admin?.(); // Ich bin Admin userGuest.admin?.(); // nichts passiert (keine solche Methode)
Hier verwenden wir in beiden Zeilen zunächst den Punkt ( userAdmin.admin
), um die admin
Eigenschaft abzurufen, da wir davon ausgehen, dass das user
vorhanden ist und es daher sicher daraus gelesen werden kann.
Dann überprüft ?.()
den linken Teil: Wenn die admin
Funktion vorhanden ist, wird sie ausgeführt (das gilt für userAdmin
). Andernfalls (für userGuest
) stoppt die Auswertung ohne Fehler.
Die Syntax ?.[]
funktioniert auch, wenn wir Klammern []
verwenden möchten, um auf Eigenschaften anstelle von dot zuzugreifen .
. Ähnlich wie in früheren Fällen ermöglicht es das sichere Lesen einer Eigenschaft von einem Objekt, das möglicherweise nicht vorhanden ist.
let key = "firstName"; let user1 = { Vorname: „John“ }; let user2 = null; alarm( user1?.[key] ); // John alarm( user2?.[key] ); // undefiniert
Wir können auch ?.
mit delete
:
Benutzer löschen?.name; // Benutzername löschen, wenn Benutzer vorhanden ist
Wir können ?.
zum sicheren Lesen und Löschen, aber nicht zum Schreiben
Die optionale Verkettung ?.
hat auf der linken Seite einer Aufgabe keine Verwendung.
Zum Beispiel:
let user = null; user?.name = "John"; // Fehler, funktioniert nicht // weil es Folgendes ergibt: undefiniert = „John“
Die optionale Verkettung ?.
Die Syntax hat drei Formen:
obj?.prop
– gibt obj.prop
zurück, wenn obj
existiert, andernfalls undefined
.
obj?.[prop]
– gibt obj[prop]
zurück, wenn obj
existiert, andernfalls undefined
.
obj.method?.()
– ruft obj.method()
auf, wenn obj.method
existiert, andernfalls wird undefined
zurückgegeben.
Wie wir sehen, sind sie alle unkompliziert und einfach zu bedienen. Der ?.
Überprüft den linken Teil auf null/undefined
und ermöglicht die Fortsetzung der Auswertung, wenn dies nicht der Fall ist.
Eine Kette von ?.
ermöglicht den sicheren Zugriff auf verschachtelte Eigenschaften.
Trotzdem sollten wir uns bewerben ?.
vorsichtig, nur dort, wo es gemäß unserer Codelogik akzeptabel ist, dass der linke Teil nicht existiert. Damit uns etwaige Programmierfehler nicht verborgen bleiben.