Start · Sprachen · JavaScript · Referenz · Object.prototype.valueOf()

Object.prototype.valueOf()

Methode

Gibt den <code>this</code>-Wert als Objekt zurück; wird bei der Umwandlung in einen primitiven Wert automatisch aufgerufen und lässt sich überschreiben.

seit JavaScript ES1 (Baseline: alle Browser) Kategorie: method-property

Signatur

Object.prototype.valueOf()

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

Typ
Object
Beschreibung
Der 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);
true object true

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));
2494 true Preis: 19.99 EUR [ '4.95 EUR', '5.00 EUR', '19.99 EUR' ]

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`);
1709280000000 Dauer: 90 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()
valueOf() 20 valueOf() 10 toString() zehn

// 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 mit toString(). Liefern beide keinen primitiven Wert, gibt es einen TypeError: Cannot convert object to primitive value.
  • + ist mehrdeutig: obj + '' nutzt den Hinweis "default" und ruft zuerst valueOf() auf, nicht toString(). Für eine sichere Umwandlung in Text besser String(obj) oder ein Template-Literal verwenden.
  • Vorrang von Symbol.toPrimitive: Ist [Symbol.toPrimitive] definiert, wird valueOf() bei der automatischen Umwandlung gar nicht aufgerufen.
  • Strikte Gleichheit: === löst keine Umwandlung aus. new Money(100) === 100 ist false, == dagegen true. Zwei Objekte werden auch mit == nur nach Identität verglichen, valueOf() spielt dabei keine Rolle.
  • Objekte mit null-Prototyp (Object.create(null)) haben kein valueOf(). Arithmetik mit ihnen wirft einen TypeError.
  • Ü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.