webfussel

blogfussel

kleiner dev blog von webfussel

Booleans für n00bs

Zeug, das ihr beachten solltet

Booleans sind einfach. Zumindest für die meisten von uns. Nach einiger Zeit benutzen wir sie, ohne großartig darüber nachzudenken - und das ist auch gut so.
Doch vor allem bei Anfängern fallen mir einfach immer wieder die gleichen “Fehler” auf. Fehler deshalb in Anführungsstrichen, weil’s funktioniert… aber ist halt derb hässlich. Oder unnötig.
Darüber wollte ich schon länger mal schreiben und ich glaube jetzt zum Neustart ist einfach mal eine wundervolle Möglichkeit gekommen das in die Wege zu leiten.

Da ich JavaScript Developerin bin, ist dieser Artikel natürlich immer etwas durch die Web Frontend Brille betrachtet, aber vieles davon findet sicher auch Anwendung in anderen Sprachen.

Was sind Booleans?

Hier erstmal ein paar Basics für alle, die noch gar keinen Plan haben.

Grundlegendes

Booleans sind sogenannte Wahrheitswerte. Das heißt, sie sind einfach wahr oder falsch - oder besser noch: true oder false.
Sie gehören zu den wichtigsten und grundlegendsten Dateitypen überhaupt und kommen in etlichen Sprachen vor. Sie ermöglichen uns zum Beispiel Code zu verzweigen oder schleifen zu durchlaufen. Man kann sie auch selbstverständlich deshalb ganz simpel in Variablen speichern.

const bool = true
if (true) doSomething()
if (false) doSomethingElse()
else doSomethingElserigeres()
while (true) doSomethingForever()

(Oh, du hasst meine fehlenden geschweiften Klammern? Too bad. 🙃)

Implizit und Explizit

Grundsätzlich gibt es zwei Arten an Booleans zu kommen: implizite und explizite Auswertung.

const explicit = true // true
const implicit = 13 > 37 // false
const anotherImplicit = someVar === 42 // vielleicht true? mal schauen.

Explizite Zuweisung passiert zumindest meiner Erfahrung nach seltener als die implizite, was, wenn man genauer darüber nachdenkt, auch irgendwie Sinn ergibt, da man häufiger Variablen vergleichen will. Aber beides ist natürlich überaus legitim, sinnvoll und richtig - es kommt halt wie bei (fast) allem in der Entwicklung einfach drauf an.

Anwendungsfälle

In den vorigen Codeblöcken schon einmal kurz angerissen kommen hier jetzt ein paar Beispiele für Booleans in der Anwendung. Beachtet bitte, dass diese nur zur Veranschaulichung dienen, was heißt:

  • Ja, ich weiß, dass man das in der Praxis wahrscheinlich anders macht
  • Kann ja auch gut sein, dass es nicht so performant ist
  • Und ja, ist vielleicht auch was, das man so nie braucht ABER DARUM GEHT’S NET
  • Es kann gut sein, dass hier schon andere Kenntnisse nötig sind um alles richtig zu verstehen
// Logge alle geraden Zahlen auf die Konsolenausgabe
for (let i = 0; i < 10; i++) {
    if (i % 2 === 0) { // implizites Boolean, überprüft ob ZAHL geteilt durch 2 einen Restwert von 0 ergibt, wodurch die Zahl eben gerade ist
        console.log(i)
    }
}

// Führe essen aus, wenn true ansonsten führe hungern aus
if (someString.indexOf('pizza') > -1) { // die String-Funktion indexOf überprüft ob eine zeichenkette im String vorkommt und gibt dann ihren index zurück, -1 wenn nicht vorhanden
    essen()
} else {
    hungern()
}

Verbesserungspotenzial

So, damit müssten die Grundlagen erstmal grob erläutert sein. Ich wollte euch ja keine Booleans selbst richtig beibringen - sondern euch zeigen, was ihr n00bs in der Anwendung noch verbessern könnt!

Returns, der absolute Klassiker

Oh man, wie oft hab ich sowas wie folgenden Code schon gelesen:

const checkIfExists = (someString, searchMe) => {
    if (someString.includes(searchMe)) {
        return true
    } else {
        return false
    }
}

Auf den ersten Blick sieht daran erstmal nichts falsch aus, wenn man es nicht besser weiß. Aber klopfen wir das einfach mal komplett runter:

// Wir brauchen keinen else Block, wenn wir schon im if ein return ausführen
// (nur als Tipp am Rande)
const checkIfExists = (someString, searchMe) => {
    if (someString.includes(searchMe)) {
        return true
    }
    return false
}

// Im Prinzip sagen wir hier ja auch "if true return true" und das ist doch mal mega dämlich!?
// String.includes gibt uns ja schon einen boolean zurück der true oder false ist, also...
const checkIfExists = (someString, searchMe) => {
    return someString.includes(searchMe)
}

// ... und weil wir in einer arrow function sind...
const checkIfExists = (someString, searchMe) => someString.includes(searchMe)

Ja, das funktioniert so ziemlich immer, wenn die Funktion wie oben aussieht. Wirklich pupsegal, ob wir da jetzt ein explizites Boolean zurückgeben oder ein Implizites.

const isEven = number => number % 2 === 0
const checkIfStringHasDigit = string => string.test(/\d/g)
Next one: Ternaries

Japp, auch in Ternaries les ich häufig echt üblen Müll, teils geschrieben von Senior Developern. Eins der schlimmsten Dinge war (VON EINEM SENIOR DEVELOPER!!!):

// [...]
return someBoolean === true ? true : false

Das ist halt einfach genau die gleiche Kacke wie oben, nur in kurz. Wenn das schon ein Boolean ist, der nur true oder false sein kann, was soll denn die Abfrage? Wurde natürlich gleich refactored zu:

// [...]
return someBoolean

(Goldene Pfadfinderregel: Verlasst den Ort besser als ihr ihn vorgefunden habt.)

In JavaScript (und sicher auch woanders): Truthy und Falsy

Jetzt gibt es aber auch je nach Sprache auch etwas unsauberere Varianten eines Booleans - die sogenannten truthy und falsy Werte.
Die gibt es nicht überall, aber ich weiß immerhin, dass sie in JavaScript existieren.
An sich sind das Werte, die nicht explizit als true oder false aber aufgrund ihres (fehlenden) Inhaltes als solche interpretiert werden.

Beispiele:

  • 0 => falsy
  • undefined => falsy
  • null => falsy
  • Alles andere als 0 => truthy
  • Leerer string => falsy
  • Leeres array => falsy

Die Dinger sind nützlich. Die verkürzen uns viel. Dennoch können sie auch echt heimtückisch sein, wenn man die Kleinigkeit missachtet doch bitte drei Gleichheitszeichen === bei Vergleichen zu nutzen. Wichtig dabei ist: Wenn wir falsy values ein Ausrufezeichen voransetzen, dann bekommen wir den Gegenteiligen Boolean:

const isTrue = !0 // 0 => falsy, also !falsy, also !false => true

Noch cooler ist hier, dass wir damit auch locker die Booleanrepräsentation eines Wertes herausfinden können, indem wir einfach zweimal negieren:

const isFalse = !!0

Kommen wir zu: Gute Idee - Schlechte Idee (Danke Animaniacs für die Inspiration vor 25 Jahren)

// Gute Idee
if (someString) doSomething() // Macht nur etwas, wenn der String befüllt ist

// Schlechte Idee
const message = number || 'Keine Zahl vorhanden' // Schreibt den String in die Variable, wenn number nicht vorhanden ist ODER number === 0 ist
// BO-BO-BO Bonus Round!
const message = number ?? 'Keine Zahl vorhanden' // Funktioniert wie vorhin, aber diesmal gilt die 0 als Zahl

// Gute Idee
const isOdd = n => !(n%2) // Da 0 ein falsy value ist, ist das Gegenteil von 0 einfach true

// Schlechte Idee
const checkIfFalse = someVar => someVar == false // Mäh. Kommt drauf an. Wir haben hier zwei Gleichheitszeichen. Wenn du also wirklich auf FALSE prüfen willst, nicht auf falsy, dann ist das einfach falsch.

Und hier noch ein paar Fun Facts welche Ergebnisse man erzielt, wenn man nur zwei Gleichheitszeichen == nutzt.

0 == false // true
[] == false // true
'' == false // true
true == {} // false
false == {} // false
[] == {} // false
0 == '' // true

Abschließend

Insgesamt waren das meine größten Gedanken zu dem Thema. Vor allem so ein if (true) return true Zeug seh ich doch echt immer wieder unnötigerweise.
Eventuell sensibilisiert euch der Beitrag ja ein wenig.

Das wäre cool.

Das wars

Danke fürs Lesen!

Kategorien