Warunki w JavaScript

Cześć! To jest fragment książki JavaScript od podstaw, która ma pomóc w nauce programowania od zera.

Instrukcja warunkowa if

Często zdarza się, że chcemy coś zrobić tylko w pewnych przypadkach. Na przykład reklamy moglibyśmy wyświetlać tylko dla darmowych kont, albo jeśli wiadomość pochodzi od osoby zablokowanej, to powinniśmy ją ukrywać. Ponadto, jeśli post jest promowany, to powinien mieć odpowiednią etykietę "Promowany".

Aby w kodzie zrobić coś pod określonym warunkiem, powinniśmy użyć instrukcji warunkowej if. Zaczynamy od słowa kluczowego if, po czym musimy umieścić nawias, w którym znajdzie się warunek (ang. condition). Warunek to wyrażenie1 zwracające wartość logiczną (czyli true lub false). Można go utworzyć na przykład przy użyciu znaku porównania ===, < czy !==. Za nawiasami z warunkiem powinniśmy w nawiasach klamrowych określić jakie instrukcje mają zostać wykonane, gdy warunek jest spełniony (zwraca true). Jeśli nie jest spełniony (zwraca false) to instrukcje w ciele nie zostaną wykonane.

if (true) {
  console.log("To się wypisze"); // To się wypisze
}

if (false) {
  console.log("A to nie");
}

const tweetType = "promotional";
const tweetOwner = "marcinmoskala";
const yourKey = "yourname";

if (tweetType === "promotional"){
  console.log("Promowany"); // Promowany
}

if (tweetOwner === yourKey) { // false,
  // ponieważ "marcinmoskala" nie jest równe "yourname"
  console.log("Twój tweet");
}

// Wypisze się:
// To się wypisze
// Promowany

Wcięcia w kodzie i formatowanie

Zauważ, że każdą linię w ciele warunku poprzedzają dodatkowe spacje. Nazywamy je wcięciami. Służą one czytelnikowi kodu do odróżnienia co znajduje się w ciele warunku, a co poza nim. Analogiczne wcięcia będziemy mogli obserwować przy pętlach i funkcjach. Nie są one konieczne by nasz kod działał, ale warto o nich pamiętać, bo dzięki nim łatwiej jest zrozumieć, co jest częścią ciała warunku, a co nie. Zobaczysz, szybko się do nich przyzwyczaisz i Tobie również będą pomagały w szybszym zrozumieniu kodu.

W książce stosuję wcięcia na 2 spacje. Zamiast tego często stosuje się wcięcia na 4 spacje.

Zestaw reguł określający jak powinien wyglądać kod nazywany jest formatowaniem. Określa on: jakie powinny być wcięcia, gdzie stawiamy entery i spacje, jak nazywamy zmienne itp. Formatowanie może się różnić w zależności od projektu. To, które stosuję w książce, zalicza się do jednego z bardziej popularnych (miejscami jednak stawiam dodatkowe entery, by nie wyjechać poza margines).

Wywołanie warunkowe z alternatywą if-else

Ciało w instrukcji warunkowej if zostanie wywołane tylko wtedy, gdy warunek będzie spełniony. Co zrobić w sytuacji, gdybyśmy chcieli wykonać jakąś akcję również przy warunku niespełnionym? Załóżmy na przykład, że jeśli tweet jest promowany, to powinien się wyświetlić tekst "Promowany", a w przeciwnym przypadku "Zwykły". Zatem moglibyśmy użyć dwóch instrukcji warunkowych if: jednej sprawdzającej warunek, a drugiej jego odwrotność. Przeważnie taka potrzeba zdarza się często, a więc do instrukcji warunkowej if możemy dodać na końcu blok else określający, co powinno się stać w przeciwnym wypadku.

const tweetType = "standard";

if (tweetType === "promotional") {
  console.log("Promowany");
} else {
  console.log("Zwykły");
}

// Efekt ten sam, co gdybyśmy zrobili:
if (tweetType === "promotional") {
  console.log("Promowany");
}
if (tweetType !== "promotional") {
  console.log("Zwykły");
}

Zauważ, że zawsze zostanie wywołane albo ciało z if, albo ciało z else. Ten fakt często się wykorzystuje, gdy na przykład używamy if-else do ustawienia wartości zmiennej.

const tweetType = "standard";

let label;
if (tweetType === "promotional") {
  label = "Promowany";
} else {
  label = "Zwykły";
}
console.log(label); // Zwykły

label zawsze będzie miało pewną wartość - w zależności od wartości tweetType albo "Promowany", albo "Zwykły".

If-else-if

Co natomiast, gdy mamy więcej alternatyw: na przykład kilka warunków, które kolejno chcemy sprawdzać? Aby obsłużyć każdą z tych wartości, moglibyśmy połączyć kilka kolejnych instrukcji warunkowych if-else, tworząc tzw. instrukcję warunkową if-else-if.

Przykładowo, gdybyśmy chcieli obsłużyć kilka możliwych wartości tweetType:

  • promotional oznaczające tweet promowany,
  • followed oznaczające tweet osoby obserwowanej,
  • own oznaczające tweet zalogowanego użytkownika.
if (tweetType === "promotional") {
  console.log("Promowany");
} else if (tweetType === "followed") {
  console.log("Zwykły");
} else if (tweetType === "own") {
  console.log("Własny");
} else {
  console.log("Inny");
}

// To samo co
if (tweetType === "promotional") {
  console.log("Promowany");
} else {
  if (tweetType === "followed") {
    console.log("Zwykły");
  } else {
    if (tweetType === "own") {
      console.log("Własny");
    } else {
      console.log("Inny");
    }
  }
}

Alternatywę stanowi użycie switch-case, którego zdecydowałem się nie opisywać w tej książce. Zainteresowanym polecam doczytać na jego temat.

Kiedy kod nam się uruchamia, JavaScript sprawdza kolejne warunki i dla pierwszego, który będzie spełniony, wywoła jego blok kodu. Po tym sprawdzanie się kończy. Zawsze więc wywoła się dokładnie jedno ciało. Jeśli żaden warunek nie zostanie spełniony, to wywoła się blok zdefiniowany po ostatnim else. Instrukcja if-else-if reprezentuje więc różne, wykluczające się alternatywy.

W powyższym przypadku, jeśli tweetType będzie równe "promotional", to pojawi się tekst "Promowany". Jeśli będzie równe "followed", to zobaczymy komunikat "Zwykły". Jeśli będzie równe "own", to etykieta zmieni się na "Własny". Jeśli żadne z powyższych nie jest prawdziwe, to wyświetli się "Inny".

Warto zwrócić uwagę na to, że w if-else-if tylko jeden blok może zostać wywołany. W poniższym przykładzie wykorzystujemy ten fakt. Pierwszy blok zostanie wywołany, gdy wartość percent jest większa lub równa 95. Drugi, gdy jest większa lub równa 80 oraz mniejsza niż 95. Trzeci, gdy jest większa lub równa 50 i mniejsza niż 80. Natomiast ostatni tylko wówczas, gdy wartość jest mniejsza niż 50.

console.log("Czy to jest pewne?");
if (percent >= 95) {
  console.log("Na 100%");
} else if (percent >= 80) {
  console.log("Raczej tak");
} else if (percent >= 50) {
  console.log("No, powiedzmy");
} else {
  console.log("eeee");
}

Ćwiczenie: Warunki

Poniżej przedstawiam cztery warianty wartości zmiennych userNameuserAge, oraz trzy fragmenty kodu. Dla każdej pary odpowiedz na pytanie: jak zachowa się dany kod dla określonych wartości zmiennych? (udziel łącznie 12 odpowiedzi: dla każdej kombinacji wariantu i fragmentu)

Wariant pierwszy

const userName = "Michał";
const userAge = 31;

Wariant drugi

const userName = "Prezes Marek";
const userAge = 61;

Wariant trzeci

const userName = "Paweł";
const userAge = 10;

Wariant czwarty

const userName = "";
const userAge = 14;

Pierwszy fragment kodu - warunek if

if (userName === "Prezes Marek") {
  console.log("Witamy Pana Prezesa");
}

if (userName !== "") {
  console.log("Cześć " + userName);
}

if (userAge < 18) {
  console.log("Może czekoladkę?");
}

if (userAge >= 18) {
  console.log("Może coś do picia?");
}

Drugi fragment kodu - warunek if-else

if (userName === "Prezes Marek") {
  console.log("Witamy Pana Prezesa");
} else {
  console.log("Cześć " + userName);
}

if (userAge < 18) {
  console.log("Może czekoladkę?");
} else {
  console.log("Może coś do picia?");
}

Trzeci fragment kodu - warunek if-else-if

if (userName === "Prezes Marek") {
  console.log("Witamy Pana Prezesa");
} else if (userName !== "") {
  console.log("Cześć " + userName);
}

if (userAge <= 10) {
  console.log("Kategoria: Dzieci");
} else if (userAge <= 20) {
  console.log("Kategoria: Młodzież");
} else if (userAge <= 60) {
  console.log("Kategoria: Dorośli");
} else {
  console.log("Kategoria: Starsi");
}

Odpowiedzi na końcu książki.

Operator warunkowy

Często spotykaną alternatywą dla if-else jest tzw. operator warunkowy, najczęściej znany jako ternary operator2. Trzy przyjmowane przez niego wartości oddziela najpierw znak zapytania ?, a potem dwukropek :. Oznaczają one kolejno:

  • warunek,
  • wartość, która powinna być zwrócona, gdy warunek jest spełniony,
  • wartość, która powinna być zwrócona, gdy warunek nie jest spełniony.

console.log(true ? "AAA" : "BBB"); // AAA
console.log(false ? "AAA" : "BBB"); // BBB

const type = "promotional";
const owner = "marcinmoskala";
const yourKey = "yourname";

const label = type === "promotional" ? "Promowany" : "";
console.log(label); // Promowany

const author = owner === yourKey ? "Twój" : "@" + owner;
console.log(author); // @marcinmoskala

Operator warunkowy mógłby być zastąpiony przez if-else. Zwykle preferuje się go w przypadku, gdy zależy nam tylko na ustawieniu odpowiedniej wartości, ze względu na krótszy i uproszczony zapis.

let result = condition ? value1 : value2;

// To alternatywa do

let result;
if (condition) {
  result = value1;
} else {
  result = value2;
}

Warto pamiętać, by stosować ten operator tylko wtedy, gdy jego użycie zwiększa czytelność kodu. Gdy jest nadużywany, kod staje się nieczytelny.

1:

Patrz Słowniczek na samym końcu książki.

2:

Operator to znak służący do wykonania jakiejś operacji, najczęściej matematycznej. Typowe operatory to +, -, *. Większość operatorów stawia się między dwoma wartościami. Dla przykładu: operator mnożenia stawia się między dwoma liczbami, więc jest to binary operator, od łacińskiego bi znaczącego dwa. Podobnie, operatory logiczne &&||. Operator postawiony przed pojedynczą wartością, na przykład - stawiany przed liczbą albo ! przed wartością logiczną, to operatory unarne. Ternary operator to taki, który przyjmuje 3 wartości. Ponieważ jednak operator warunkowy jest jedynym takim powszechnie znanym operatorem w programowaniu, te dwie nazwy traktowane są jako synonimy, a dla większości programistów jaśniejszym będzie, jak powiesz "ternary operator" niż "operator warunkowy".