Einleitung: Die Aufgabe, die Stack Overflow sprengte
\n\nStellen Sie sich vor: Sie sind in einem Vorstellungsgespräch und der Interviewer fragt mit einem listigen Lächeln: „Kann der Ausdruck a == 1 && a == 2 && a == 3 jemals true zurückgeben?“. Die erste Reaktion ist: „Natürlich nicht! Eine Variable kann nicht gleichzeitig drei verschiedenen Zahlen entsprechen.“
Wenn Sie jedoch JavaScript etwas tiefer kennen, wissen Sie: In dieser Sprache sind die unerwartetsten Dinge möglich. Diese Frage hat auf Stack Overflow tausende Aufrufe gesammelt und ist ein Klassiker, um das Verständnis von Typumwandlung (Type Coercion), Gettern und Objekt-Wrappern in JS zu testen.
\n\nIn diesem Artikel beweisen wir nicht nur, dass dies möglich ist, sondern zeigen Ihnen auch 5 verschiedene Methoden, um (a==1 && a==2 && a==3) zu true zu machen. Sie erfahren, wie der lockere Vergleich (==) funktioniert, wie er sich vom strikten Vergleich (===) unterscheidet und wie Sie ihn steuern können.
Dieser Artikel ist sowohl für Anfänger geeignet, die JavaScript besser verstehen wollen, als auch für erfahrene Entwickler, die sich auf ein Vorstellungsgespräch vorbereiten. Los geht‘s!
\n\nMethode Nr. 1: Die Magie von valueOf (die beliebteste)
\n\nDie eleganteste und am häufigsten zitierte Methode ist die Verwendung eines benutzerdefinierten Objekts mit überschriebener valueOf-Methode. In JavaScript ruft die Engine beim Vergleich eines Objekts mit einem primitiven Wert über == automatisch valueOf() (oder toString()) auf, um das Objekt in einen primitiven Wert umzuwandeln.
Wir erstellen ein Zähler-Objekt, das bei jedem Aufruf von valueOf seinen Wert um 1 erhöht.
const a = {\n value: 1,\n valueOf() {\n return this.value++;\n }\n};\n\nconsole.log(a == 1 && a == 2 && a == 3); // true\n\nWie es funktioniert:
\n- \n
- Beim ersten Vergleich
a == 1wirdvalueOf()aufgerufen, gibt 1 zurück, undvaluewird auf 2 erhöht. \n - Beim zweiten Vergleich
a == 2wird erneutvalueOf()aufgerufen, gibt 2 zurück, undvaluewird zu 3. \n - Der dritte Vergleich
a == 3schließt die Kette erfolgreich ab. \n
Dies ist ein perfektes Beispiel für Type Coercion (erzwungene Typumwandlung) in Aktion. Genau dieser Mechanismus macht JavaScript zu einer sowohl flexiblen als auch gefährlichen Sprache.
\n\nMethode Nr. 2: toString – der Zwilling von valueOf
\n\nWenn Sie toString anstelle von valueOf überschreiben, ist das Ergebnis dasselbe. JavaScript kann beim lockeren Vergleich jede dieser Methoden zur Umwandlung des Objekts verwenden.
const a = {\n value: 1,\n toString() {\n return this.value++;\n }\n};\n\nconsole.log(a == 1 && a == 2 && a == 3); // true\n\nDer feine Unterschied: valueOf hat bei numerischen Vergleichen Priorität, toString bei Zeichenketten-Vergleichen. In unserem Fall sind jedoch beide Ansätze perfekt geeignet.
Methode Nr. 3: Getter im globalen Gültigkeitsbereich
\n\nViele wissen nicht, dass globale Variablen in JavaScript eigentlich Eigenschaften des globalen Objekts sind (window im Browser, global in Node.js). Und Eigenschaften können über Getter definiert werden.
Wir können einen Getter für die Variable a direkt auf dem globalen Objekt definieren:
let value = 1;\nObject.defineProperty(window, 'a', {\n get() {\n return value++;\n }\n});\n\nconsole.log(a == 1 && a == 2 && a == 3); // true\n\nDiese Methode ist besonders interessant, da sich a wie eine normale Variable verhält, obwohl es sich eigentlich um eine Eigenschaft mit einem Getter handelt. Jedes Mal, wenn Sie auf a zugreifen, gibt der Getter einen neuen Wert zurück.