HOWTO · JavaScript
JavaScript-Tupel: Arrays, Objekte und TypeScript
JavaScript hat keinen nativen Tupeltyp. Verwenden Sie je nach Anforderung Arrays, Objekte, Object.freeze(), Destrukturierung oder TypeScript-Tupel.
Auf dieser Seite
JavaScript hat zur Laufzeit keinen nativen Tupeltyp. Verwenden Sie für eine kurze, geordnete Wertegruppe wie Koordinaten ein Array und zerlegen Sie es per Destrukturierung. Ein Objekt eignet sich besser, wenn Feldnamen die Daten verständlicher machen. Soll das Programm direkte Änderungen zur Laufzeit verhindern, frieren Sie das Array ein; für eine feste Länge und Elementtypen während der Entwicklung verwenden Sie ein TypeScript-Tupel.
Ein Array für ein geordnetes Wertepaar verwenden
Ein Array ist ein sinnvolles tupelähnliches Format, wenn jede Position eine feste Bedeutung hat. Diese Funktion gibt zuerst das Minimum und dann das Maximum zurück:
function minMax(values) {
return [Math.min(...values), Math.max(...values)];
}
const [minimum, maximum] = minMax([7, 3, 12]);
console.log(minimum, maximum);
Ausgabe:
3 12
Die Destrukturierung gibt den Positionen aussagekräftige lokale Namen. Dokumentieren Sie die Reihenfolge für Aufrufer. JavaScript erzwingt weder die Array-Länge noch die Elementtypen; Daten aus JSON, Speicher oder einer untypisierten Schnittstelle müssen daher vor der Destrukturierung validiert werden.
Ein Array nur bei benötigtem Laufzeitschutz einfrieren
const verhindert die Neuzuweisung einer Variablen, aber nicht die Änderung des darin gespeicherten Arrays. Object.freeze() schützt das Array selbst:
"use strict";
const point = Object.freeze([48.8566, 2.3522]);
console.log(point[0], point[1], Object.isFrozen(point));
// point[0] = 0; // TypeError in strict mode
// point.push(3); // TypeError
Ausgabe:
48.8566 2.3522 true
Object.freeze() gibt dasselbe Objekt zurück und erstellt keine Kopie. Besitzt der Aufrufer das Eingabearray weiterhin, sollten Sie es deshalb vor dem Einfrieren kopieren:
function asFrozenPoint(value) {
if (
!Array.isArray(value) ||
value.length !== 2 ||
!value.every(Number.isFinite)
) {
throw new TypeError("Expected two finite coordinates");
}
return Object.freeze([...value]);
}
Das Einfrieren ist flach. Direkte Elemente, Länge und Eigenschaften können nicht geändert werden, verschachtelte Objekte bleiben jedoch veränderbar:
const settings = Object.freeze([{ theme: "light" }]);
settings[0].theme = "dark";
console.log(settings[0].theme);
Ausgabe:
dark
Bezeichnen Sie eine flach eingefrorene verschachtelte Struktur nicht als vollständig unveränderlich. Ein rekursives Einfrieren muss unter anderem Zyklen behandeln und ist nur bei einer echten Anforderung sinnvoll.
Ein Objekt verwenden, wenn Namen wichtiger sind
Positionen werden unübersichtlich, sobald ein Wert mehrere Zeichenketten, boolesche Werte, optionale Felder oder später erweiterte Felder enthält:
function createUser() {
return { id: 42, name: "Ada", active: true };
}
const { id, name, active } = createUser();
Arrays passen zu bekannten, kompakten Paaren wie [x, y] oder den [key, value]-Einträgen von Object.entries(). Ein Objekt ist sicherer, wenn Aufrufer sonst die Bedeutung eines Index erraten müssten.
Object.entries() liefert bereits ein dokumentiertes Positionspaar. Durch Destrukturierung werden die beiden Positionen direkt an der Verwendungsstelle sichtbar:
for (const [key, value] of Object.entries({ theme: "light" })) {
console.log(`${key}: ${value}`);
}
Ausgabe:
theme: light
TypeScript für einen geprüften Tupelvertrag verwenden
TypeScript kann Länge, Reihenfolge und Elementtypen ausdrücken:
const point: readonly [number, number] = [48.8566, 2.3522];
readonly verhindert Änderungen im TypeScript-Quellcode. Nach der Kompilierung bleibt der Wert ein normales JavaScript-Array und ist nicht automatisch zur Laufzeit eingefroren. Kombinieren Sie den Tupeltyp nur dann mit Object.freeze(), wenn Sie sowohl statische Prüfung als auch Laufzeitschutz benötigen.
Zusammenfassung
JavaScript-Arrays können per Konvention wie Tupel verwendet und bequem destrukturiert werden. Wählen Sie Objekte für benannte Felder, Object.freeze() für flachen Laufzeitschutz und TypeScript-Tupel für statische Längen- und Typprüfungen.