Signatur
Beschreibung
Object.prototype.valueOf() gibt den this-Wert selbst zurück, bei Bedarf in ein Objekt umgewandelt. Die Standard-Implementierung ist also fast nichts tuend: obj.valueOf() === obj gilt für jedes gewöhnliche Objekt. Da alle Objekte von Object.prototype erben, steht die Methode überall zur Verfügung, außer bei Objekten mit null-Prototyp (Object.create(null)).
Wirklich nützlich wird valueOf() erst, wenn man es überschreibt. JavaScript ruft die Methode automatisch bei der Umwandlung in einen primitiven Wert auf, z. B. bei arithmetischen Operatoren (+, -, *), Vergleichen (<, >), bei loser Gleichheit (==) mit Primitiven und bei der unären Umwandlung +obj. Mit dem Hinweis "number" oder "default" wird zuerst valueOf() und danach toString() versucht; mit dem Hinweis "string" (z. B. in Template-Literalen oder bei String(obj)) ist die Reihenfolge umgekehrt.
Eingebaute Typen überschreiben die Methode bereits: Number.prototype.valueOf(), String.prototype.valueOf() und Boolean.prototype.valueOf() geben den verpackten primitiven Wert zurück, Date.prototype.valueOf() liefert den Zeitstempel in Millisekunden. Deshalb kann man zwei Date-Objekte direkt voneinander abziehen.
Eigene Klassen, die einen natürlichen Zahlenwert haben (Geldbeträge, Maßeinheiten, Versionsnummern), können mit einem eigenen valueOf() direkt mit Operatoren verglichen und verrechnet werden. Wer mehr Kontrolle braucht, etwa ein unterschiedliches Verhalten für Zahlen- und Text-Kontext, greift besser zu Symbol.toPrimitive.
Rückgabewert
this-Wert, umgewandelt in ein Objekt. Bei überschriebenen Varianten meist ein primitiver Wert (z. B. number). Wird die Methode mit null oder undefined als this aufgerufen, wirft sie einen TypeError.Beispiele
Standardverhalten: gibt das Objekt selbst zurück
const config = { debug: true };
console.log(config.valueOf() === config);
// Mit primitivem this wird ein Wrapper-Objekt erzeugt
const wrapped = Object.prototype.valueOf.call(42);
console.log(typeof wrapped, wrapped instanceof Number);
Eigene Klasse mit Zahlenwert: Geldbeträge rechnen und vergleichen
class Money {
constructor(cents, currency = 'EUR') {
this.cents = cents;
this.currency = currency;
}
valueOf() {
return this.cents;
}
toString() {
return `${(this.cents / 100).toFixed(2)} ${this.currency}`;
}
}
const preis = new Money(1999);
const versand = new Money(495);
console.log(preis + versand); // valueOf() → 2494
console.log(preis > versand); // true
console.log(`Preis: ${preis}`); // Template-Literal nutzt toString()
const warenkorb = [new Money(500), preis, versand];
warenkorb.sort((a, b) => a - b);
console.log(warenkorb.map(String));
Date.valueOf(): Zeitdifferenz direkt berechnen
const start = new Date('2024-03-01T08:00:00Z');
const ende = new Date('2024-03-01T09:30:00Z');
console.log(start.valueOf());
const minuten = (ende - start) / 60_000; // Subtraktion ruft valueOf() auf
console.log(`Dauer: ${minuten} Minuten`);
Wann valueOf() aufgerufen wird – Protokoll
const probe = {
valueOf() { console.log('valueOf()'); return 10; },
toString() { console.log('toString()'); return 'zehn'; }
};
console.log(probe * 2); // Hinweis "number"
console.log(probe + ''); // Hinweis "default" → trotzdem valueOf()
console.log(`${probe}`); // Hinweis "string" → toString()
// Wichtig · Fallstricke
- Primitiver Rückgabewert nötig: Gibt ein überschriebenes
valueOf()ein Objekt zurück, wird es bei der Umwandlung ignoriert und JavaScript versucht es mittoString(). Liefern beide keinen primitiven Wert, gibt es einenTypeError: Cannot convert object to primitive value. +ist mehrdeutig:obj + ''nutzt den Hinweis"default"und ruft zuerstvalueOf()auf, nichttoString(). Für eine sichere Umwandlung in Text besserString(obj)oder ein Template-Literal verwenden.- Vorrang von
Symbol.toPrimitive: Ist[Symbol.toPrimitive]definiert, wirdvalueOf()bei der automatischen Umwandlung gar nicht aufgerufen. - Strikte Gleichheit:
===löst keine Umwandlung aus.new Money(100) === 100istfalse,==dagegentrue. Zwei Objekte werden auch mit==nur nach Identität verglichen,valueOf()spielt dabei keine Rolle. - Objekte mit
null-Prototyp (Object.create(null)) haben keinvalueOf(). Arithmetik mit ihnen wirft einenTypeError. - Überschriebene Umwandlungen können Code schwer lesbar machen. Nur einsetzen, wenn der Zahlenwert eines Objekts wirklich eindeutig ist.
- Kompatibilität: Die Methode gibt es in allen Browsern und in Node.js seit den ersten JavaScript-Versionen.