Signatur
Beschreibung
Normalerweise ruft JavaScript valueOf() automatisch auf, wenn ein Objekt in einen primitiven Wert umgewandelt werden muss, zum Beispiel bei <, >, - oder +. Bei Temporal.PlainMonthDay ist diese Methode absichtlich so gebaut, dass sie immer einen TypeError wirft. Ausdrücke wie md1 < md2 oder md1 - md2 scheitern also sofort mit einem Fehler und liefern kein stilles, falsches Ergebnis.
Der Grund: Bei Date gibt valueOf() einen Zeitstempel zurück. Deshalb funktionieren Vergleiche dort scheinbar, verleiten aber oft zu Fehlern. Temporal verlangt dagegen, dass du ausdrücklich sagst, was du willst. Für PlainMonthDay gibt es zudem keine statische Methode compare(), weil die Reihenfolge von Monat und Tag ohne Jahr und Kalender nicht eindeutig ist. Auf Gleichheit prüfst du mit equals(). Zum Sortieren wandelst du den Wert mit toPlainDate({ year }) in ein festes Jahr um und nutzt dann Temporal.PlainDate.compare().
In Zeichenketten umwandeln lässt sich die Instanz trotzdem: Template-Literale und String(md) rufen über Symbol.toPrimitive mit dem Hinweis „string“ die Methode toString() auf. valueOf() kommt dabei nicht zum Zug. Der Operator + mit einer Zeichenkette ("" + md) nutzt dagegen den Hinweis „default“, ruft zuerst valueOf() auf und wirft deshalb ebenfalls.
Rückgabewert
TypeError.Beispiele
Vergleichsoperatoren lösen einen TypeError aus
const geburtstag = Temporal.PlainMonthDay.from('03-14');
const heute = Temporal.PlainMonthDay.from('07-01');
try {
console.log(geburtstag < heute);
} catch (err) {
console.log(err instanceof TypeError); // true
}
Richtig: Gleichheit mit equals() prüfen
const weihnachten = Temporal.PlainMonthDay.from({ month: 12, day: 24 });
const heute = Temporal.Now.plainDateISO();
const istHeiligabend = weihnachten.equals(heute.toPlainMonthDay());
console.log(istHeiligabend ? 'Frohe Weihnachten!' : 'Noch nicht Heiligabend');
Sortieren über ein festes Bezugsjahr
const termine = ['12-24', '02-29', '07-04', '01-01']
.map((s) => Temporal.PlainMonthDay.from(s));
// Schaltjahr als Bezug, damit der 29. Februar gültig bleibt
const sortiert = termine.toSorted((a, b) =>
Temporal.PlainDate.compare(
a.toPlainDate({ year: 2024 }),
b.toPlainDate({ year: 2024 })
)
);
console.log(sortiert.map((md) => md.toString()));
String-Konvertierung: Template-Literal ja, + nein
const md = Temporal.PlainMonthDay.from('10-03');
console.log(`Feiertag: ${md}`); // ruft toString() auf
console.log(String(md));
try {
console.log('Feiertag: ' + md); // Hinweis "default" führt zu valueOf()
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Fallstrick
+-Operator:'Text ' + mdwirft einen Fehler. Verwende Template-Literale,String(md)odermd.toString(). - Kein
compare(): Anders alsPlainDateoderPlainTimehatPlainMonthDaykeine statische Vergleichsmethode. Zum Sortieren wandelst du in einPlainDatemit festem Jahr um. Nimm ein Schaltjahr, sonst wird der02-29auf den02-28verschoben. ==und===vergleichen Objektreferenzen und werfen keinen Fehler. Zwei gleiche Monat-Tag-Werte ergeben trotzdemfalse. Nutzeequals().- JSON:
JSON.stringify()funktioniert, weiltoJSON()vorhanden ist.valueOf()wird dabei nicht aufgerufen. - Kompatibilität: Temporal ist noch nicht in allen Browsern verfügbar (Safari fehlt bisher). Bei Bedarf hilft ein Polyfill wie
@js-temporal/polyfillodertemporal-polyfill.