JavaScript 10.11
Operatory i konwersja typów
Automatycznie JS próbuje wykonać konwersje danych podczas tych operacji
Operator dodawania - służy do sumowania wartości liczbowych lub do łączenia stringów. Jeśli jeden z operandów/argumentów które mamy jest stringiem to ten operator zmienia swoje zachowanie i zamiast operacji matematycznej robi operacje łączenia znaków const suma = 10+5;
Operator odejmowania - jeśli operandy mają wartość liczbową, to te wartości się odejmą const roznica = 10-5;
Operator mnożenie iloczyn = 10*5;
Operator dzielenie iloraz= 10/5;
Operator modulo reszta = 10% 3; czy liczba jest podzielna przez daną liczbę, bardzo użyteczny w sprawdzaniu parzystości liczb, w wykrywaniu i implementowaniu logiki cyklicznej co czwarty raz zrób coś np.
Operator potęgowania potega = 2**3; można użyć funkcji matematycznej ale to jest łatwiejsze
Operatory porównania
Zwracają boolean - true/false.
porównania luźne - porównania, które automatycznie konwertują typy danych, a w związku z tym ułatwiają życie, ale mogą prowadzić do błędów
const liczba=5; const tekst="5";
const luznaRownos = liczba == tekst;
const scislaRownosc = liczba === tekst; nie tylko wartości, ale konwersja - jesli wartosci sie nie zgadzaja ich typ, to sie nie zgadzaja, wiec
Nierównosci
const luznieNierownie = liczba != tekst;
const scielseNierowne = liczba!== tekst;
Operatory relacyjne
> wieksze const wieksze = 10>5;
< mniejsze con
>= wiekszeLubRowne
Konwersja jawna/niejawna
Implicit conversion javascript sam konwertuje
Explicit conversion my to robimy
ParseInt liczby całkowite
ParseFloat liczby zmiennoprzecinkowe
Number - przekształca na wartość liczbową (Number.isNan() test czy dana konwersja jest możliwa
String() można skonwertować 123 na string
Boolean() prawda/fałsz 0/1
Falsy traktowane jako fałsz: false, 0,-0, 0n (bigInt ma osobne bo to inny typ danych), " ", null, undefined, NaN
Truthy traktowane jako true: true, 1, -1, "0" "false" " " "tekst, bez jawnego porównania możemy sprawdzić czy użytkownik coś nam wpisał, jest to dośc powszechna praktyka
const imie =""; const maImie = Boolean(imie);
Pusty string daje false
Type Coercion niektóre rzeczy są nieintuicyjne
Badanie/Walidacja inputu od uzytkownika:
inputWartosc =25; jeśli bnedzie ="25aaa" to tez skonwertuje ale jeśli jest na poczatku aaa25 to wtedy nie skonwertuje
const liczba = number(inputWartosc);
czypoprawna =!isNan(liczba);
Jeśli mamy formularz, dobrym pomysłem na input od uztykownika jest użycie funkcji trim (usuwa zbede spacje z poczatku i konca)
STOSOWAĆ OPERATORY SCISLE, porównywać nie tylko wartości ale i typy używać JAWNĄ KONWERSJE TYPÓW
Operatory logiczne
Operator AND (&&) zwraca true jeśli oba operandy są truthy, uzywamy kiedy chcemy sprawdzić czy wszystkie warunki sa spełnione np. czy użytkownik jest zalogowany i czy ma uprawnienia do jakiejś operacji
Operator OR (||) zwraca true kiedy chociaż jeden z operandów jest truthy, używamy jeśli chcemy sprawdzic czy jaikolwiek warunek z anszej listy jest spełniony, czesto uzywanmy do ustawiania wartosci domyslnych
Operator NOT (!) operator negujacy wartosc, zamienia truthy na falsy, czesto używany czy coś nie jest prawda albo konwersji wartości na boolean, dwa zaprzeczenia podwójna negacja zwroci true przy !!1;
Operatory logiczne nie zawsze zwracają boolean, mogą zwracać jeden z operandow, jeśli stworzymy taka logikę (nowoczesny sposób SHORT CIRCUIT).
Możemy łączyć operatory
const wiek =25; const maKonto = true; const mozeKupic = wiek >= 18&& maKonto;
Łączenie AND i OR działają logiki matematyki
SHORT CIRCUIT EVALUATION używany by skrócić zapis i wykonać test a po tescie odrazu pokazywać wartość, AND i Or
const wynik1 = false && console.log ("to się nie wykona"); NIE wykona sie jak oba elementy nie sa prawdziwe true
const wynik2= true && "to sie zwróci";
w jednej linijce przypisujemy wartość domyślna i wykonujemy sprawdzenie. Gdzie używać np. obiekty
const miasto=uzytkownik&& uzytkownik.adres && uzytkownik.adres.miasto
Sprawdzamy czy istnieje obiekt, czy w obiekcie istnieje obiekt podrzędny i czy obiekt podrzędny nie jest pusty
Działa dla OR
W ten sposób jesteśmy w stanie walidować rożnego rodzaju wartości, czy to walidować funkcje, czy to zwraca wartości które są prawidłowe.
Nullish coalescing ?? rozwiązuje problem z używaniem operatora OR do ustawiania wartości domyślnych
Jeśli w OR pierwsza wartość jest false to będzie falsy wiec jak ustawimy domyślna wartość na 0 to przy użyciu operatora OR to nie weźmie tego pod uwagę, a w przypadku kiedy tworzymy domyślne konfiguracje to może zdarzyć się tak, że domyślna wartość dla nas to 0. Operator ten nie może być użyty z AND i OR bez użycia nawiasów - zabezpiecza to przed niejednoznacznością, a nawias mówi która operacja ma być wykonana jako pierwsza.
Optional Chaining ?. upraszcza prace z zagnieżdżonymi obiektami, np. z właściwościami które w tych obiektach mogą nie istnieć
Jeśli wartości która sprawdza nie ma to zwraca undefined
Optional Chaining działa też z funkcjami, może sprawdzić czy metoda stworzona w funkcji istnieje. A jeśli nie istnieje to jest undefined a nie brak bledu wiec nam nie wywali kodu - miękkie sprawdzenie graceful error handling
Działa tez z tablicami np. czy dany index istnieje, a jeśli nie istnieje daje undefined
Optional Chaining można ustawić wartości domyślne, jeśli jakaś wartość domyślna nie jest ustawiona to można wtedy jej to przypisać
Operator Precendence pierwszeństwo operatorów, który operator ma się pierwszy wykonać
- operatory arytmetyczne wyższe niż porównania
- porównania wyższe niz op logiczne
- nawiasy najwyższe pierwszeństwo
NOT, AND, OR - w takiej kolejności wykonują się operatory logiczne
Inne operatory:
Przypisz jeśli zmienna turthy &&=
Przypisz jeśli zmienna falsy ||=
Przypisz jeśli zmienna null/undefined ??=
Przydatne przy warunkowym modyfikowaniu obiektów, kod jest b zwięzły, ale nie jest to konieczne.
Podsumowanie:
Jeżeli używamy notacji short circuit i jeśli poprawna wartością jest 0 lub false lub pusty string to zamiast OR || używamy nullish coalesing ??
Jeżeli potrzebujemy dostać się do wartości obiektu i chcemy to zrobić w sposób bezpieczny, jeśli tej wartości nie ma, klucz nie istnieje itd. używamy optional chaning ?.
operator precendence
Instrukcje warunkowe
IF
IF jeżeli, sprawdza czy w wyrażeniu które jest podane w nawiasie jest prawdziwe, jeśli tak wykonuje blok kodu, oceniamy czy truthy czy falsy, nie musi byc boolean.
if (wiek >= 18) { console.log("użytkownik jest pełnoletni");}
Instrukcje if mogą być zagnieżdżone
if (punkty >=50) { console.log ('test zaliczony");
if (punkty >=80) { console.log("doskonały wynik")};
mogą być też złożone z więcej niż 1 warunku
if (temperatura > 20 && jestSlonecznie) { console.log("świetna pogoda na spacer");}
Zmienne mogą być w instrukcji ale mogą być zadeklarowane globalnie
ELSE rozszerza możliwości IF pozwala na określenie kodu w przeciwnym wypadku jeżeli nie. Pozwala na podzielenie logiki, jeśli cos nie, to wtedy to
Musi być umieszczony bezpośrednio po bloku IF i nie może istnieć samodzielnie
Podstawowy IF-ELSE
const godzina =14;
if(godzina <12) { console.log("dzień dobry");} else { console.log("dobry wieczór");} pokaże dobry wieczor bo warunek nie jest spełniony
ELSE-IF zostanie wykonana pierwszy spełniony warunek, ignoruje pozostałe, umieszczamy między IF a ELSE. Kolejność warunków ma znaczenie, jeśli warunki się pokrywają to te b. specyficzne powinny być sprawdzanie jako pierwsze
if
else if
else if
else if
else
W instrukcjach warunkowych możemy łączyć operatory logiczne i arytmetyczne.
Instrukcja przestanie działać w momencie kiedy pierwszy z warunków zostanie spełniony.
Teoretycznie jest możliwe nie używanie nawiasów klamrowych, jeśli mamy tylko 1 instrukcje, ale lepiej używać nawiasów klamrowych zawsze w każdym przypadku, nawet dla jednej linii kodu. Jeżeli mamy złożone warunki, to zwracać uwagę na nazwy zmiennych, by nazwy zmiennych były opisowe nosiły informacje, bo inaczej ciężko się intepretuje złożone warunki jeżeli one nie są opisowe.
Unikać zbyt głębokiego zagnieżdżania, tak samo jak w tabelach listach itd. Jeśli kod ma więcej niż 3 poziomy zagnieżdżenia, staje się ciężki do śledzenia.
Rozważyć czy negative conditionals zaprzeczenia są konieczne, zwłaszcza gdy warunki są skomplikowane, może nie są potrzebne.
Switch
alternatywa dla długich łancuchów if-else. Szczególnie przydatna jeżeli porównujemy sprawdzamy wartość która ma potencjalnie wiele wartości. Każdy case reprezentuje jedną wartość. Jeśli case zostanie znaleziony kod bloku zostanie wykonany. Switch został zaprojektowany tak, ze używa ścisłego porównania oznacza to ze typ danych musi się zgadzać, jeśli badamy liczby string nie działa itp. Na końcu każdego bloku umieszczamy break; to daje informacje do przeglądarki do JS, ze jak ten kod się wykona to cały switch ma się zakończyć.
default - opcjonalny, działa dokładnie tak samo jak else w if-else, wykonuje się wtedy jeśli żaden z case nie pasuje
Switch może występować z wyrażeniami np. &&
Instrukcją warunkową if sprawdzamy obie liczby, natomiast instrukcja switch wybieramy działanie które na tych liczbach się wykona
// Pobranie danych od użytkownika
let liczba1 = prompt("Podaj pierwszą liczbę:");
let liczba2 = prompt("Podaj drugą liczbę:");
let operacja = prompt("Wybierz operację: +, -, *");
// Konwersja na liczby
liczba1 = parseFloat(liczba1);
liczba2 = parseFloat(liczba2);
// Sprawdzenie, czy to faktycznie liczby
if (isNaN(liczba1) || isNaN(liczba2)) {
alert("Podano nieprawidłową liczbę!");
} else {
// Wybór operacji
let wynik;
switch (operacja) {
case "+":
wynik = liczba1 + liczba2;
break;
case "-":
wynik = liczba1 - liczba2;
break;
case "*":
wynik = liczba1 * liczba2;
break;
default:
alert("Nieznana operacja!");
wynik = null;
}
// Jeśli wszystko OK – pokaż wynik
if (wynik !== null) {
console.log(`Wynik: ${liczba1} ${operacja} ${liczba2} = ${wynik}`);
alert(`Wynik: ${liczba1} ${operacja} ${liczba2} = ${wynik}`);
}
}
Fall-through grupowanie wartości np. podajemy w case dzień tygodnia i od pon do pt podaje dzień roboczy robimy break dla przypadku sobot niedziela wypada typdnia weekend, potem znow break. Fall-thorugh to przepuszczanie do kolejnych caseów, jeśli brakuje instrukcji break to JS przechodzi do kolejnych caseów, on nie sprawdza case tylko wykonuje kod, on nie sprawdza tych warunków tylko dla tych wszystkich warunków to X jest spełniony. Jak jest break to kończy kod, jak nie ma break to będzie wykonywać wszystkie warunki/opcje. Najlepiej wpisać komentarz ze to jest celowe fall-through.
TERNARY krótsza notacja zapisu if-else, można przypisać do zmiennej wartości
Ternary można używać w wyrażeniu
Można używać jako wywoływanie funkcji
NIE ZAGDNIEŻDZAĆ TERNARY
Pętle
Po co stosować pętle - jak mamy wiele operacji, możemy zautomatyzować kod, nie musimy go przepisywać x razy, ale możemy go wsadzić w pętle
Pętla w JS składa się z 3 części
Warunek początkowy - ustawienie kiedy pętla startuje
Warunek który ma być spełniony i jak długo ten warunek jeśli spełniony ma działać
Implementacja czyli ile razy pętla ma działać
Wszystkie instrukcje które umieścimy w pętli
FOR
for (let i =1; i<=5; i++) {console.log(i);} wykona się bo let to zmienna blokowa, i jest zdefiniowana w ciele pętli i jest specyficzna dla tego kawałku bloku. Jeśli byśmy używali var to by sie nadpisywały te zmienne
Dla pierwszej pętli używamy i - iterator, dla kolejnych pętli używamy j, k itd.
Dla wygody dla siebie można zadeklarować zamiast i swoja zmienna która będziemy rozumieć
Jako, ze tablice adresowane są od 0, konwencje programistyczne zachęcają by pętle również zaczynać od 0
i++ do przodu, jeśli chcemy co dwa co trzy co pięć i=i+7 i+=7
i- - wstecz
Iteracja po tablicy
Działają w FOR wszystkie operatory, operacje.
sumowanie wartości += do bieżącej wartości dodaje i
Można w for wyszukiwać w tablicy
Możemy budować w pętli elementy HTML - np. listy punktowane, mamy do wyświetlenia kawałek tablicy, obiektu itd i wyświetlić chcemy kawałek tego np. kartę użytkownika
WHILE
działa jak for, wykonuje kod dopóki warunek jest prawdziwy. For ma wszystkie części kontrolne w jednym miejscu, while wymaga ręczne zarządzanie zmiennymi sterującymi, wymaga od nas więcej uwagi
let licznik=5; zadeklarowana zmienna przed pętlą
while (licznik>0){
console.log(licznik);
licznik - -
}
While z flagą kontrolną
const liczby - tablica
let indeks ustawiamy na 0 by zacząć od 1 pozycji
let znaleziono = false na poczatek ustawiamy
ustawiamy warunek, tak długo warunek ma się kręcić jak indeks liczby ma być mniejszy od długości tablicy indeks < liczby.lenght && !znaleziono i kręcimy tak długo pętla jak długo indeks jest w zakresie, jesli znajdziemy warunek to zmieniamy zmienna znaleziono=true
Jak źle wybierzemy warunki inicjalizacji to pętla w ogóle się nie wykona np. let x=10, while x<5 nie działa
DO...WHILE
Chociaż raz, ale zawsze się wykona. Pobieranie hasła użytkownika, pobieranie wartości do kalkulatora. Zrób to i to jeśli (tu można wsadzić ify), while na końcu. Pobieramy dane a potem sprawdzamy warunki dodatkowe
while wykona się tylko wtedy kiedy warunek jest spełniony, jak warunek nie dobry while jest pomijany
do while najpierw wykona kod a potem sprawdzi warunek, wiec chociaż raz pętla się wykona
WHILE z break jak licznik ma np. 3 to pętla się zakończy, jak nie ma jasnego warunku kiedy pętla ma się zakończyć, wiec lepiej np skontrolować ze się wykona x razy - gry w JS spora część while (true) rób, jeśli, przerwij, koniec
break- wczesne zakończenie pętli
continue - nie zatrzymuj się na tej iteracji, idź dalej, np. pomiń liczby parzyste
Zagnieżdżone pętle - breaki działają na konkretne pętle