Boolean ist mit nur zwei Werten — true und false — der einfachste Primitive-Typ. Trotzdem ist er Quelle für überraschend viele Bugs. Grund: JavaScript coerced in Boolean-Kontexten (if, while, &&, ||, !) jeden Wert automatisch zu Boolean. Genau 8 Werte zählen als falsy, alles andere ist truthy — auch leere Arrays, leere Objekte und der berüchtigte new Boolean(false)-Wrapper. Wer diese Liste nicht im Kopf hat, baut subtile Logik-Fehler. Dieser Artikel klärt die acht Falsy-Werte, die wichtigsten Truthy-Fallen und warum !!x der idiomatische Weg zum Boolean ist.

Zwei Werte, ein Primitive

Boolean ist mit nur zwei möglichen Ausprägungen — true und false — der minimalste Datentyp. Wie alle Primitives ist er immutable und wird per Wert verglichen.

JavaScript grundlagen.js
const aktiv = true;
const sichtbar = false;

typeof aktiv;     // 'boolean'
typeof false;     // 'boolean'

// Vergleichs-Operatoren liefern Boolean
typeof (5 > 3);   // 'boolean'
typeof !sichtbar; // 'boolean'

// Logische Operatoren liefern NICHT immer Boolean (siehe Section 7)
typeof ('a' || 'b');  // 'string' (!)
Output
boolean
boolean
string

Der Boolean-Kontext

Wann immer JavaScript einen Wert in einem Boolean-Kontext braucht — if, while, ternär ?:, &&, ||, !, Boolean(), !! — wird der Wert implizit zu true oder false coerced. Die Spezifikation legt genau acht Werte fest, die zu false coerced werden. Alles andere wird zu true.

Das Konzept ist mächtig — if (user) prüft elegant auf „existiert und ist gesetzt" — aber die genaue Liste muss im Kopf sitzen, sonst entstehen subtile Bugs.

JavaScript boolean-kontext.js
// alle Boolean-Kontexte
if (wert)        { /* … */ }
while (wert)     { /* … */ }
wert ? 'a' : 'b';
wert && 'next';
wert || 'fallback';
!wert;
Boolean(wert);
!!wert;

// Beispiel: existiert die Antwort?
const response = fetchSync();
if (response) {
    // truthy: response ist gesetzt UND nicht leer
}
Output

Vollständige Liste

Es gibt genau acht Werte, die in Boolean-Kontexten zu false werden. Diese Liste ist seit ES6 stabil — mit 0n (BigInt) wurde sie erweitert.

WertTypAnmerkung
falseBooleander Boolean selbst
0Numbernumerische Null (auch 0.0, 0x0)
-0Numbernegative Null — eigenes Bit-Muster
0nBigIntBigInt-Null (seit ES2020)
''Stringleerer String (auch "" und ` `)
nullNullabsichtliche Abwesenheit
undefinedUndefinednicht zugewiesen / Default-Parameter
NaNNumberNot-a-Number
JavaScript falsy-liste.js
// alle 8 falsy
Boolean(false);     // false
Boolean(0);         // false
Boolean(-0);        // false
Boolean(0n);        // false
Boolean('');        // false
Boolean(null);      // false
Boolean(undefined); // false
Boolean(NaN);       // false

// Sonderfall: document.all (Legacy-DOM, im Browser)
// ist ebenfalls falsy — historischer Spec-Hack
Output
false

Was überraschend truthy ist

Die wichtigste Lehre aus der Falsy-Liste: alles andere ist truthy. Das umfasst einige Werte, die intuitiv „leer" oder „falsch" wirken.

JavaScript truthy-fallen.js
// alle Objects sind truthy — auch wenn sie leer sind
Boolean([]);            // true  — leeres Array!
Boolean({});            // true  — leeres Object!
Boolean(new Map());     // true
Boolean(new Date());    // true  — auch Invalid Date

// Strings: Inhalt egal, nur Leerheit zählt
Boolean('0');           // true  — String 'null' wäre auch truthy
Boolean('false');       // true
Boolean(' ');           // true  — Whitespace zählt!

// Numbers: nur Null und NaN sind falsy
Boolean(-1);            // true
Boolean(Infinity);      // true
Boolean(0.0001);        // true

// Funktionen: immer truthy
Boolean(() => {});      // true
Output
true
true
true

Explizite Konvertierung

Es gibt zwei idiomatische Wege, einen beliebigen Wert zu Boolean zu coercen — beide funktional identisch.

JavaScript coercion.js
// Variante 1: Boolean() als Funktion (NICHT mit new!)
Boolean('hi');     // true
Boolean(0);        // false
Boolean([]);       // true

// Variante 2: doppelte Negation — idiomatischer
!!'hi';            // true   — !'hi' ist false, !!… ist true
!!0;               // false
!![];              // true

// beide äquivalent — Wahl ist Stilfrage
// Linter wie ESLint erlauben meist beide

// praktischer Use-Case: API-Antwort zu sauberem Boolean
const hasItems = !!response?.items?.length;
const isLoggedIn = Boolean(user?.id);
Output
true
false
true

!! ist kürzer und in der JavaScript-Community Standard, Boolean() ist expliziter und für Anfänger lesbarer. Wichtig: niemals new Boolean(value) — das erzeugt einen Object-Wrapper (siehe Section 8).

if (x) vs. if (x === true)

Implizites Boolean-Coercion in if-Statements ist Standard-Praxis. Der explizite Vergleich === true ist fast immer falsch — er prüft nicht „Wahrheit", sondern „ist exakt der Boolean true".

JavaScript if-vergleich.js
const flag = 1;

// implizit (idiomatisch)
if (flag) {
    // läuft, weil 1 truthy ist
}

// explizit — wird NICHT eintreten!
if (flag === true) {
    // läuft NICHT, weil 1 !== true (verschiedener Typ)
}

// sinnvoll: wenn API garantiert nur Boolean zurückgibt
const isAdmin = checkAdmin();  // gibt streng Boolean zurück
if (isAdmin === true) {
    // okay als Type-Guard / API-Contract-Check
}

// mit ?: für Fallback-Werte
const name = user.name || 'Anonym';     // Fallback bei falsy
const safe = user.name ?? 'Anonym';     // Fallback nur bei null/undefined
Output

Short-Circuit gibt den Operanden zurück

Eine der wichtigsten Eigenheiten von && und || in JavaScript: sie geben nicht immer einen Boolean zurück, sondern den letzten ausgewerteten Operanden. Dieses Verhalten ist ES1-alt und wird konstant für Defaults und Guards eingesetzt.

JavaScript short-circuit.js
// || gibt ersten truthy zurück, sonst letzten Wert
'a' || 'b';        // 'a'
'' || 'b';         // 'b'
0 || null || 'x';  // 'x'
0 || null;         // null  — letzter Wert, alle falsy

// && gibt ersten falsy zurück, sonst letzten Wert
'a' && 'b';        // 'b'
'' && 'b';         // ''
true && null;      // null
true && 'x' && 5;  // 5

// praktischer Einsatz: Default-Wert
const port = config.port || 3000;
// ABER: bei port=0 würde der Fallback ungewollt greifen!

// ?? statt || für "nur null/undefined als leer"
const port2 = config.port ?? 3000;  // nur fallback bei null/undefined
Output
a
b
x

new Boolean(false) ist truthy

Die wahrscheinlich berüchtigtste JavaScript-Falle. Wie alle Primitives hat Boolean einen Object-Wrapper — new Boolean(value). Das Resultat ist ein Object, und alle Objects sind truthy. Auch der Wrapper um false.

JavaScript wrapper-anti-pattern.js
const wrapper = new Boolean(false);

typeof wrapper;          // 'object'  (!)
wrapper === false;       // false
wrapper.valueOf();       // false   — der innere Wert ist false

// aber im Boolean-Kontext: TRUTHY!
if (wrapper) {
    console.log('Das läuft!');  // wird ausgeführt
}

Boolean(wrapper);        // true   — alle Objects sind truthy

// Boolean() OHNE new ist die korrekte Coercion
Boolean(false);          // false  — gut
new Boolean(false);      // Object — schlecht

// gleiche Falle wie new String(''), new Number(0)
Output
object
Das läuft!

In über 25 Jahren JavaScript hat dieses Pattern keinen einzigen sinnvollen Use-Case gefunden — der Wrapper-Konstruktor ist heute nur noch Spec-Altlast. Linter wie ESLint warnen mit der Regel no-new-wrappers.

Wann === true sinnvoll ist

Trotz der Faustregel „immer implizit prüfen" gibt es Fälle, in denen === true die richtige Wahl ist — nämlich dort, wo das API-Contract garantiert nur Boolean liefern soll und ein anderer Wert ein Bug-Indikator wäre.

JavaScript strict-checks.js
// Type-Guard: prüfen, ob der Wert wirklich Boolean ist
function istEchterBoolean(x) {
    return typeof x === 'boolean';
}

// API-Contract: Funktion soll garantiert Boolean liefern
function isValid(input) {
    // … Logik …
    return result === true;  // nur exakt true zählt
}

// bei Drittanbieter-API, wo "truthy" nicht reicht
if (response.success === true) {
    // unterscheidet zwischen 1, 'ok', {…} und echtem Boolean
}

// praktisch: Filter-Predicates
[true, 1, 'true', null].filter(x => x === true);  // [true]
[true, 1, 'true', null].filter(Boolean);          // [true, 1, 'true']
Output
[ true ]

In TypeScript-Codebasen ist === true seltener nötig, weil der Compiler den Typ ohnehin zu Boolean engt. In Vanilla-JS ist es ein nützliches Werkzeug für defensive Validierung.

Typische Fallen mit Truthy/Falsy

new Boolean(false) ist TRUTHY — der Klassiker

Der Object-Wrapper ist immer truthy, auch wenn er false umschließt. if (new Boolean(false)) läuft in den then-Zweig. Das gleiche Muster gilt für new String('') und new Number(0). Lehre: Boolean(value) als Funktion aufrufen, niemals mit new. Linter-Regel: no-new-wrappers.

Leeres Array [] ist TRUTHY

Alle Objects sind truthy, und Arrays sind Objects — auch wenn sie leer sind. if (arr) sagt also nur „arr existiert", nicht „arr enthält etwas". Korrekt: if (arr.length > 0) oder if (arr?.length). Gleiche Falle bei , new Map() und new Set().

'0' ist TRUTHY (String), 0 ist FALSY (Number)

Form-Inputs kommen aus dem DOM immer als String. Ein Eingabefeld mit Wert '0' ist truthy, der numerische Wert 0 nach parseInt wäre falsy. Das ist eine der häufigsten Quellen für „funktioniert lokal, aber nicht im Prod"-Bugs. Lösung: vor dem Test in den richtigen Typ konvertieren.

NaN ist FALSY — und nie gleich sich selbst

Boolean(NaN) ist false, aber NaN === NaN ist ebenfalls false. Wer auf NaN prüfen will, kann nicht x === NaN schreiben — das ist immer false. Korrekt: Number.isNaN(x). Für Boolean-Kontexte ist das Verhalten konsistent: NaN wirkt wie „leer".

?? berücksichtigt nur null und undefined als "leer"

Der Nullish-Coalescing-Operator ?? ist nicht dasselbe wie ||. 0 || 'fallback' ergibt 'fallback', 0 ?? 'fallback' ergibt 0. Wichtig bei numerischen oder Boolean-Defaults, bei denen 0, '' oder false gültige Werte sind. Mit || würden sie ungewollt überschrieben.

!!x ist idiomatischer als Boolean(x)

Beide sind funktional identisch und beide vom Linter erlaubt. !! ist in der JS-Community Standard, kürzer und in einer Expression-Position lesbarer (const has = !!list.length). Boolean() ist für Anfänger expliziter. Wichtig nur: niemals new Boolean().

if (obj) prüft Existenz, nicht Inhalt

if (response) sagt nur „response ist nicht null/undefined/0/leer-String". Es sagt nichts darüber, ob die Antwort sinnvoll ist. if (response.success) ist eine separate Prüfung — und wenn response selbst undefined wäre, würde die Property-Lese einen TypeError werfen. Optional Chaining (response?.success) löst das elegant.

Date-Objekte sind IMMER truthy — auch Invalid-Date

new Date('foo') erzeugt einen Invalid Date — das Object existiert, ist aber im Inneren NaN. Trotzdem ist es als Object truthy: Boolean(new Date('foo')) ist true. Wer auf Validität prüfen will: !Number.isNaN(date.getTime()) oder date instanceof Date && !isNaN(date).

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Datentypen

Zur Übersicht