Now Reading
Nullreferenzen: So vermeiden Sie den “Billion-Dollar Mistake” in JavaScript und TypeScript

Nullreferenzen: So vermeiden Sie den “Billion-Dollar Mistake” in JavaScript und TypeScript

Nullreferenzen: So vermeiden Sie den "Billion-Dollar Mistake" in JavaScript und TypeScript

Nullreferenzen sind die vermutlich häufigste Ursache pro Laufzeitfehler in vielen Programmiersprachen. Neue JavaScript-Sprachfeatures sowie Compilerparameter in TypeScript helfen, den “Billion-Dollar Mistake” zu vermeiden.

JavaScript dürften jene Fehler aufgrund dieser fehlenden statischen Typisierung noch einmal klar häufiger hervortreten. Zwei mit ECMAScript 2020 eingeführte Operatoren vereinfachen den Umgang mit nullishen Werten. TypeScript bietet vereinen Compilerparameter an, um Nullreferenzausnahmen nachdem Möglichkeit zu vermeiden.

In vielen Programmiersprachen ist es möglich, einer Variable, die mit einem Objekttyp deklariert wurde, den Zahl “null” zuzuweisen, etwa in Kohlenstoff#:

Person person = null;

Dieses Vorgehen führt jedoch zu einem Problem, wenn Entwickler davon zu Ende gehen, dass sich ein passendes Objekt in dieser Variable befindet und versuchen, Eigenschaften davon zu dereferenzieren. Dann kommt es während dieser Spielzeit zu einer Nullreferenzausnahme:

person.Name
// NullReferenceException!

Fehler im Zusammenhang mit Nullreferenzen dürften zu den häufigsten Programmierfehlern zur Spielzeit in Besitz sein von. Tony Hoare, dieser Tüftler dieser Nullreferenz, entschuldigte sich 2009 publik pro seinen “Billion-Dollar Mistake”, die Lehrbuch dieser Null-Verweis in Algorithmic Language Wolfram. In modernen Sprachen wie Swift oder Kotlin ist die oben gezeigte Zuweisung von “nil” bzw. “null” standardmäßig nicht erlaubt, sondern nur pro optionale beziehungsweise nullable Typen:

let person: Person? = nil

Viele Sprachen nach sich ziehen seitdem nachgezogen: In Kohlenstoff# und TypeScript können Entwickler per Opt-in ebenfalls hinauf eine striktere Null-Prüfung setzen und die Gefahr von Nullreferenzausnahmen zur Spielzeit klar reduzieren. Mit dem Sprachlevel ECMAScript 2020 wurden wenige neue Operatoren in JavaScript eingeführt, um den Umgang mit nullishen Werten zu vereinfachen. Jene kommen sogar TypeScript-Entwicklern zugute.

Zwei nullishe Werte in JavaScript

Zunächst ist festzuhalten, dass JavaScript zwei “nullishe” Werte verfügt, “null” selbst und “undefined”. Während “null” laut Sprachstandard dasjenige absichtliche Fehlen eines Wertes repräsentiert, deshalb tendenziell explizit gesetzt wird, handelt es sich “undefined” um den Zahl, wenn einer Variable bisher kein Zahl zugewiesen wurde, deshalb sogar implizit entstehen kann. In JavaScript ist dasjenige Abrufen nicht existierender Eigenschaften eines Objektes möglich, nicht jedoch dasjenige Abrufen von Eigenschaften hinauf “null” oder “undefined”:

const foo = { Kneipe: null };
foo.Kneipe // null
foo.baz // undefined
foo.baz.qux // TypeError: Cannot read properties of
// undefined ≈ NullReferenceException

Ternärausdrücke: Welcher Klassiker

Welcher erste, von jeher mögliche Weg, in JavaScript und TypeScript mit solchen Werten umzugehen, ist dieser aus vielen Sprachen bekannte Ternärausdruck:

const name = person ? person.name : 'Keine Person gewählt';

Dieserfalls ist jedoch Vorsicht geboten, denn die Prämisse vor dem Auswahloperator ? wird im Kontrast zu den im Folgenden vorgestellten Operatoren qua boolscher Zahl interpretiert: In JavaScript werden nicht nur false, null oder undefined im Kontext dieser Konvertierung nachdem Boolean zu false folgerichtig, sondern sogar die Werte 0, NaN, oder dieser leere Zeichenkette. Von dort kann die Prämisse sogar in Fällen greifen, die vielleicht nicht beabsichtigt waren.

Optional Chaining: Elvis has entered the building

Mit dem Sprachlevel ECMAScript 2020 wurde dasjenige sogenannte Optional Chaining (Operator ?.) in JavaScript eingeführt. Dieses Kurs hat viele Namen: Es ist sogar qua Safe Navigation von Rang und Namen; dieser Operator wird gerne sogar qua ELVIS-Operator bezeichnet, dasjenige qua Akronym pro Evaluate Left Value If Set stillstehen soll, oder, um 90 Qualität nachdem rechts gedreht, an Elvis Presleys Schmalztolle erinnert.

Ausdrücke werden von sinister nachdem rechts ausgewertet. Eine Dereferenzierung findet beim Optional Chaining jeweils nur dann statt, wenn die ausgewertete Faktor nicht die Werte null oder undefined enthält. Andernfalls wird pro den kompletten Wort dieser Zahl undefined zurückgegeben.

const foo = { Kneipe: 3, baz: null };
foo?.Kneipe // 3
foo?.baz // null
foo?.baz?.qux // undefined

Eine Nullreferenzausnahme tritt hier zur Spielzeit nun deshalb nicht mehr hinauf, sogar wenn nicht existierende Eigenschaften (wie etwa “qux” von dieser Faktor “baz”) abgerufen werden. Weniger von Rang und Namen ist, dass dasjenige Optional Chaining sogar im Kontext Indexzugriffen und Methodenaufrufen funktioniert. Dieserfalls muss den Klammern pro die Parameterauflistung beziehungsweise dem Indexausdruck ein Zähler vorangestellt werden:

dialog.canClose?.()
person.awards?.[0]

Nullish Coalescing: Fallbacks definieren

Wohnhaft bei Verwendung des Nullish-Coalescing-Operators (??) wird dieser linke Wort zurückgegeben, vorausgesetzt er nicht null oder undefined ist, des Weiteren dieser rechte Wort. Diesen Operator gibt es schon seither längerem in Kohlenstoff#. Genutzt wird er typischerweise, um Standard- oder Fallback-Werte zu definieren, sollte dieser gesuchte Zahl nicht definiert sein:

const people = response.people ?? [];

Für jedes diesen Operator gibt es sogar eine passende Variante pro Zuweisungen:

people ??= []

In allen Fällen ist Vorsicht geboten

In allen gezeigten Fällen muss Bedachtsamkeit werden, dass es sich jeweils um implizite Verzweigungen handelt. Die zyklomatische Kompliziertheit ist hinauf einem sehr kompakten Codeausschnitt folglich sehr hoch. Zu diesem Zweck lassen sich mithilfe von Optional Chaining und Nullish Coalescing sogar kompliziertere Fälle in einer Zeile Kode erläutern. Nachstehend wird dieser Fallback-Zahl “Unbekannter Name” festgesetzt, wenn entweder “person” oder “person.name” null oder undefined sind:

const name = person?.name ?? 'Unbekannter Name';

Während sich mithilfe dieser gezeigten Operatoren Fehler zur Spielzeit vermeiden lassen, bleibt zumindest in JavaScript dasjenige Problem, dass Entwicklern von Rang und Namen sein muss, welche Variable nullishe Werte enthalten kann. Hier eilt TypeScript zur Hilfe.

TypeScript hilft mit strictNullChecks

TypeScript bietet vereinen Compileroption namens strictNullChecks an, die dasjenige oben geschilderte Verhalten von Swift und Kotlin sogar in TypeScript nachliefert. Welcher Zahl undefined darf nur noch dann zugewiesen werden, wenn ein nullable Type verwendet wird:

const anna: Person = null; // Unzulässig mit strictNullChecks
const peter: Person | null = null; // Zulässig mit strictNullChecks

Wohnhaft bei Verwendung von nullable Typen zu tun sein Entwickler erst prüfen, dass wirklich ein Objekt hinterlegt ist. Andernfalls sind Dereferenzierungen nicht erlaubt:

peter.name // Unzulässig mit strictNullChecks

if (peter) {
peter.name // Zulässig mit strictNullChecks
}

Wenn Entwickler sich sicher sind, dass sich ein Zahl in einer Variable mit nullable Typ befindet, gilt es zudem noch den Non-Null-Assertion-Operator – passenderweise ein Rufzeichen. Dann die Erlaubnis haben potenziell unsichere Zugriffe wieder durchgeführt werden:

peter!.name // Zulässig mit strictNullChecks

Da dieser Operator den Sicherheit jedoch wieder aushebelt, sollte nachdem Möglichkeit hinauf seinen Hinterlegung verzichtet werden. Vorsicht ist weiterhin geboten, da trotz strictNullChecks die Initialisierung einer Klasseneigenschaft nicht verpflichtend ist:

private anna: Person; // Zulässig mit strictNullChecks

Um sogar aus dieser Fehlerquelle auszusteigen, kann die Compileroption strictPropertyInitialization aktiviert werden. Dann zu tun sein leer Klasseneigenschaften, die nicht-nullable Typen aufzeigen, immer zwingend mit einem Zahl initialisiert werden. Es empfiehlt sich, jene Compileroption im Kontext dieser Verwendung von strictNullChecks gleich mit zu anschalten. Dann dürfte dieser Quelltext vor Nullreferenzausnahmen weitestgehend geschützt sein. Wohnhaft bei TypeScript gilt dies wohlgemerkt nur zur Compilezeit, denn während dieser Explikation im Browser findet keine Typprüfung statt. Probleme kann es dann etwa spendieren, wenn dieser Server nicht mit dieser Erwiderung antwortet, die dieser TypeScript-Kode erwartet.

Die spätere Wanderung einer Codebase hinauf strictNullChecks und strictPropertyInitialization zieht nicht selten vereinen hohen Kosten nachdem sich und macht sogar viele subtile Bugs visuell. Punktum diesem Grund empfiehlt es sich, jene Compileroptionen im Kontext neuen Projekten von vornherein anzuschalten oder eine anstehende Wanderung nicht nachhaltig aufzuschieben.

Fazit

Gleichermaßen wenn es viele Satzzeichen in die Codebase einführt: Optional Chaining, Nullish Coalescing und Nullable Types verbessern die Robustheit von in JavaScript bzw. TypeScript geschriebenen Programmen erheblich, während sie vereinen dieser häufigsten Laufzeitfehler zu vermeiden helfen. Für jedes Anwendungen größeren Umfangs ist die Lehrbuch einer strikteren Nullprüfung stark empfohlen. So schaltet sogar dasjenige SPA-Framework Angular seither Version 12 pro leer neuen Projekte nicht aufgefordert strictNullChecks und strictPropertyInitialization ein.

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

Scroll To Top