Rozdział 2. Podstawy języka JavaScript

10 września 2012
1 gwiadka2 gwiazdki3 gwiazdki4 gwiazdki5 gwiazdek

Wprowadzenie

Podstawę biblioteki jQuery stanowi JavaScript, który sam w sobie jest niezwykle bogatym i ekspresyjnym językiem. W poniższej sekcji poznamy podstawowe pojęcia języka JavaScript, a także przyjrzymy się czekającym na nowicjuszy pułapkom. Omówione zagadnienia skierowane są przede wszystkim do początkujących, jednak zapoznanie się z charakterystycznymi cechami JavaScriptu może przynieść korzyści również programistom mającym doświadczenie w innych językach programowania.

Jeśli chcesz dowiedzieć się więcej na temat języka JavaScript, gorąco polecam książkę Douglasa Crockforda JavaScript: The Good Parts oraz nasz kurs programowania w języku JavaScript autorstwa Marijna Haverbeke

Podstawy składni JavaScriptu

Omówienie instrukcji, nazewnictwa zmiennych, białych znaków oraz innych podstawowych elementów składni języka JavaScript.

Przykład 2.1. Prosta deklaracja zmiennej

var foo = 'witaj, świecie';

Przykład 2.2. Poza cudzysłowem białe znaki nie pełnią żadnej funkcji

var foo = 'witaj, świecie';

Przykład 2.3. Nawiasy oznaczają pierwszeństwo wykonywania działania

2 * 3 + 5;    // zwraca 11; pierwsze wykonywane jest mnożenie
2 * (3 + 5);  // zwraca 16; pierwsze wykonywane jest dodawanie

Przykład 2.4. Tabulatory zwiększają czytelność kodu, lecz nie mają żadnego specjalnego znaczenia

var foo = function() {
    console.log('witaj');
};

Operatory JavaScript

Podstawowe operatory

Używając podstawowych operatorów możemy manipulować wartościami.

Przykład 2.5. Łączenie (konkatenacja)

var foo = 'witaj,';
var bar = 'świecie';

console.log(foo + ' ' + bar); // witaj, świecie

Przykład 2.6. Mnożenie i dzielenie

2 * 3;
2 / 3;

Przykład 2.7. Inkrementacja i dekrementacja

var i = 1;

var j = ++i;  // preinkrementacja:  j równa się 2; i równa się 2
var k = i++;  // postinkrementacja: k równa się 2; i równa się 3

Operacje na liczbach i ciągach znaków

Czasem liczby i ciągi w języku JavaScript mogą zachowywać się nie do końca zgodnie z naszymi przewidywaniami.

Przykład 2.8. Dodawanie vs. łączenie

var foo = 1;
var bar = '2';
console.log(foo + bar);  // 12, ups

Przykład 2.9. Jak sprawić, by ciąg stał się liczbą

var foo = 1;
var bar = '2';
 // wymuszamy, aby ciąg stał się liczbą
console.log(foo + Number(bar));

Wywołanie konstruktora Number jako funkcji (tak jak w przykładzie powyżej) sprawi, że jego argument będzie traktowany jako liczba. Ten sam rezultat osiągniemy używając jednoargumentowego operatora plus:

Przykład 2.10. Jak sprawić, by ciąg stał się liczbą (przy użyciu jednoargumentowego operatora plus)

console.log(foo + +bar);

Operatory logiczne

Operatory logiczne umożliwiają oszacowanie argumentów poprzez operacje I oraz LUB.

Przykład 2.11. Operatory logiczne I oraz LUB

var foo = 1;
var bar = 0;
var baz = 2;

foo || bar;   // zwraca 1, czyli prawdę
bar || foo;   // zwraca 1, czyli prawdę

foo && bar;   // zwraca 0, czyli fałsz
foo && baz;   // zwraca 2, czyli prawdę
baz && foo;   // zwraca 1, czyli prawdę

Być może przykład nie ilustruje działania operatorów zbyt jasno, zatem krótkie wyjaśnienie: operator || zwraca wartość pierwszego argumentu, który jest prawdziwy, zaś w przypadku, gdy obydwa argumenty są fałszywe, zwracany jest ostatni argument. Operator && zwraca wartość pierwszego fałszywego argumentu, lub wartość ostatniego, jeśli obydwa argumenty są prawdziwe.

Nie zapomnij zajrzeć do sekcji „Rzeczy prawdziwe, rzeczy fałszywe”, aby dowiedzieć się więcej na temat tego, które wartości są prawdziwe (true), a które fałszywe (false).

Operatory porównywania

Dzięki operatorom porównywania możemy sprawdzić, czy dane wartości są sobie równe bądź ze sobą identyczne.

Przykład 2.12. Operatory porównywania

var foo = 1;
var bar = 0;
var baz = '1';
var bim = 2;

foo == bar;   // zwraca fałsz
foo != bar;   // zwraca prawdę
foo == baz;   // zwraca prawdę; uwaga!

foo === baz;             // zwraca fałsz
foo !== baz;             // zwraca prawdę
foo === parseInt(baz);   // zwraca prawdę

foo > bim;    // zwraca fałsz
bim > baz;    // zwraca prawdę
foo <= baz;   // zwraca prawdę

Kod warunkowy

Czasami chcemy, aby blok kodu został wykonany tylko w określonej sytuacji. Umożliwia nam to kontrola przepływu sterowania za pomocą instrukcji if-else.

Przykład 2.13. Sterowanie wykonaniem programu

var foo = true;
var bar = false;

if (bar) {
    // ten kod nigdy nie zostanie wykonany
    console.log('witaj!');
}

if (bar) {
    // kod nie zostanie wykonany
} else {
    if (foo) {
        // kod zostanie wykonany
    } else {
        // kod zostanie wykonany jeśli zarówno foo i bar będą fałszywe
    }
}

Rzeczy prawdziwe, rzeczy fałszywe

Aby umiejętnie sterować działaniem programu, należy wiedzieć, które wartości są prawdziwe, a które fałszywe. Zdarza się, że wartości, które pozornie wydają się fałszywe bądź prawdziwe zwracają przeciwną wartość.

Przykład 2.14. Wartości, które zwracają prawdę

'0';
'dowolny ciąg';
[];  // pusta tablica
{};  // pusty obiekt
1;   // dowolna liczba różna od zera

Przykład 2.15. Wartości, które zwracają fałsz

0;
'';  // pusty ciąg
NaN; // zmienna, która nie jest typu liczbowego
null;
undefined;  // uwaga – undefined może mieć zmienioną definicję!

Przypisanie warunkowe zmiennych za pomocą operatora trójargumentowego

Czasami chcemy przypisać zmiennej daną wartość w zależności od tego, czy został spełniony określony warunek. Możemy wówczas użyć instrukcji warunkowej if-else, lecz w wielu przypadkach znacznie wygodniejszym rozwiązaniem jest operator trójargumentowy. [Definicja: operator trójargumentowy sprawdza, czy został spełniony określony warunek; jeśli tak, zwracana jest odpowiednia wartość, jeśli nie — inna.]

Przykład 2.16. Operator trójargumentowy

// jeśli bar jest prawdziwe, niech foo równa się 1
// w przeciwnym wypadku niech foo będzie równe 0
var foo = bar ? 1 : 0;

Operatora trójargumentowego można używać bez przypisania zmiennej wartość zwrotnej, jednak lepiej tego nie robić.

Instrukcja switch

Czasami zamiast kilku bloków if/else-if/else wygodniej jest użyć instrukcji switch. [Definicja: instrukcja switch sprawdza wartość danego wyrażenia bądź zmiennej i wykonuje poszczególne bloki kodu zależnie od tej wartości.]

Przykład 2.17. Instrukcja switch

switch (foo) {

    case 'bar':
        alert('wartość bar – ojej!');
    break;

    case 'baz':
        alert('buu baz :(');
    break;

    default:
        alert('wszystko pozostałe może być');
    break;
}

Instrukcja switch nie jest już zbyt chętnie wykorzystywana przez programistów JavaScript, ponieważ często do osiągnięcia tych samych rezultatów można wykorzystać obiekty. Są one wygodniejsze do ponownego użycia czy testów. Na przykład:

var coMamZrobic = {
    'bar' : function() {
        alert('wartość bar – ojej!');
    },

    'baz' : function() {
        alert('buu baz :(');
    },

    'default' : function() {
        alert('wszystko pozostałe może być');
    }
};

if (coMamZrobic[foo]) {
    coMamZrobic[foo]();
} else {
    coMamZrobic['default']();
}

Obiektom przyjrzymy się bliżej w dalszej części rozdziału.

Pętle języka JavaScript

Dzięki pętlom możemy wykonać blok kodu określoną liczbę razy.

Przykład 2.18. Pętle

// rejestruje 'próba 0', 'próba 1', ..., 'próba 4'
for (var i=0; i<5; i++) {
    console.log('próba ' + i);
}
Zwróć uwagę, że choć w pętlach używamy słowa kluczowego var przed nazwą zmiennej i, to jednak „zakres” zmiennej nie ogranicza się tylko do bloku pętli. Pojęcie zakresu zmiennych zostanie dokładniej omówione w dalszej części rozdziału.

Pętla for

Pętla for składa się z czterech instrukcji. Jej struktura wygląda następująco:

for ([inicjacja]; [warunek]; [iteracja])
 [trescPetli]

Instrukcja inicjująca wykonywana jest tylko raz, przed rozpoczęciem pętli. Wówczas możemy przygotować lub zadeklarować jakieś zmienne.

Instrukcja warunkowa wykonywana jest przed każdą iteracją, a od jej wartości zwrotnej zależy dalsze wykonywanie pętli. W przypadku wartości fałszywej pętla się zatrzymuje.

Instrukcja iteracja wykonywana jest na końcu każdej iteracji — wtedy też można zmienić stan istotnych zmiennych. Zazwyczaj zwiększa bądź zmniejsza się wówczas licznik, co przybliża pętlę do końca.

TrescFunkcji wykonywana jest w czasie każdej iteracji i może zawierać dowolny kod. Zazwyczaj treść funkcji składa się z wielu instrukcji, które muszą zostać wykonane i są otoczone klamrami ({...}).

Oto typowa pętla for:

Przykład 2.19. Typowa pętla for

for (var i = 0, limit = 100; i < limit; i++) {
    // Ten blok kodu zostanie wykonany 100 razy
    console.log(Iteracja nr ' + i);
    // Uwaga: jako ostatni wyświetli się komunikat "Iteracja nr 99"
}

Pętla while

Pętla while swoją budową przypomina instrukcję warunkową if, przy czym treść tej pętli jest wykonywana aż do momentu, w którym dany warunek nie jest już dłużej spełniany.

while ([warunek]) [trescPetli]

Oto typowa pętla while:

Przykład 2.20. Typowa pętla while

var i = 0;
while (i < 100) {

    // Ten blok kodu zostanie wykonany 100 razy
    console.log('Iteracja nr ' + i);

    i++; // inkrementacja i

}

Z pewnością zauważysz, że w treści pętli musimy dokonać inkrementacji licznika. Licznik można połączyć z warunkiem, tak jak zaprezentowano poniżej:

Przykład 2.21. Pętla while, w której licznik jest inkrementowany po sprawdzeniu na nim warunku

var i = -1;
while (++i < 100) {
    // Ten blok kodu zostanie wykonany 100 razy
    console.log('Iteracja nr ' + i);
}

Zwróć uwagę, że zaczynamy z poziomu -1 i korzystamy z przedrostkowego operatora inkrementacji (++i), czyli preinkrementacji.

Pętla do-while

Jest to praktycznie taka sama pętla co while — różnica polega na tym, że treść pętli do-while jest wykonywana co najmniej jeden raz, przed sprawdzeniem warunku.

do [trescPetli] while ([warunek])

Oto pętla do-while:

Przykład 2.22. Pętla do-while

do {

    // Nawet w przypadku niespełnienia warunku
    // treść pętli zostanie wykonana raz.

    alert('Hej!');

} while (false);

Pętle tego typu wykorzystywane są dość rzadko, ponieważ tylko w nielicznych wypadkach chcemy, aby pętla została wykonana bez sprawdzenia jakiegokolwiek warunku. Mimo wszystko o istnieniu pętli do-while warto wiedzieć.

Instrukcje break i continue

Zazwyczaj zatrzymanie pętli następuje po niespełnieniu określonego warunku, lecz można do tego również doprowadzić umieszczając w treści funkcji instrukcję break.

Przykład 2.23. Zatrzymywanie pętli

for (var i = 0; i < 10; i++) {
    if (coś) {
        break;
    }
}

Możemy również chcieć kontynuować pętlę bez wykonywania jej dalszej treści — służy do tego instrukcja continue.

Przykład 2.24. Przeskakujemy do następnej iteracji pętli

for (var i = 0; i < 10; i++) {

    if (coś) {
        continue;
    }

    // Poniższa instrukcja zostanie wykonana tylko wówczas,
    // jeśli warunek coś nie zostanie spełniony
    console.log('Koniec');

}

Słowa zarezerwowane

W języku JavaScript istnieje pewna liczba „słów zarezerwowanych” — są to słowa o specjalnym znaczeniu. Słów tych należy używać w kodzie tylko zgodnie z ich określonym znaczeniem.

  • abstract
  • boolean
  • break
  • byte
  • case
  • catch
  • char
  • class
  • const
  • continue
  • debugger
  • default
  • delete
  • do
  • double
  • else
  • enum
  • export
  • extends
  • final
  • finally
  • float
  • for
  • function
  • goto
  • if
  • implements
  • import
  • in
  • instanceof
  • int
  • interface
  • long
  • native
  • new
  • package
  • private
  • protected
  • public
  • return
  • short
  • static
  • super
  • switch
  • synchronized
  • this
  • throw
  • throws
  • transient
  • try
  • typeof
  • var
  • void
  • volatile
  • while
  • with

Tablice JavaScript

Tablice to indeksowane od zera listy wartości. Dzięki tablicom można w wygodny sposób przechowywać zbiór związanych ze sobą elementów tego samego typu (na przykład ciągów), choć w rzeczywistości w tablicy mogą znajdować się różne typy elementów, w tym inne tablice.

Przykład 2.25. Prosta tablica

var mojaTablica = [ 'witaj', 'świecie' ];

Przykład 2.26. Dostęp do tablicy poprzez indeks

var mojaTablica = [ 'witaj', 'świecie', 'foo', 'bar' ];
console.log(mojaTablica[3]);   // rejestruje 'bar'

Przykład 2.27. Sprawdzamy rozmiar tablicy

var mojaTablica = [ 'witaj', 'świecie' ];
console.log(mojaTablica.length);   // rejestruje 2

Przykład 2.28. Zmiana wartości elementu

var mojaTablica = [ 'witaj', 'świecie' ];
mojaTablica[1] = 'zmieniony';
Choć istnieje możliwość zmiany wartości tablicy tak jak zaprezentowano to w przykładzie 2.28, lepiej tego unikać.

Przykład 2.29. Dodawanie elementów do tablicy

var mojaTablica = [ 'witaj', 'świecie' ];
mojaTablica.push('nowy element');
Przykład 2.30: Korzystanie z tablic
var mojaTablica = [ 'w', 'i', 't', 'a', 'j' ];
var mojCiag = mojaTablica.join('');   // 'witaj'
var mojPodzial = mojCiag.split('');  // [ 'w', 'i', 't', 'a', 'j' ]

Obiekty JavaScript

Obiekty zawierają jedną lub więcej par klucz-wartość. Kluczem może być dowolny ciąg, zaś wartość może stanowić dowolny typ wartości: liczba, ciąg, tablica, funkcja, a nawet inny obiekt.

Definicja: Kiedy jedna z wartości jest funkcją, nazywa się ją metodą danego obiektu. W pozostałych przypadkach wartości nazywane są własnościami lub atrybutami.

Jak się okazuje, praktycznie wszystko w języku JavaScript jest obiektem — tablice, liczby, funkcje, a nawet ciągi. Każde z nich ma swoje własności i metody.

Przykład 2.31. Tworzymy „literał obiektowy”

var mojObiekt = {
    przywitajSie : function() {
        console.log('witaj');
    },

    mojeImie : 'Joanna'
};

mojObiekt.przywitajSie();            // rejestruje 'witaj'
console.log(mojObiekt.mojeImie);   // rejestruje 'Joanna'

1 komentarz

  1. dzięki za artykuł, z tym ze przez błędy w prostych przykładach trochę to słabo wszystko wypada.
    Bo wydaje się ze rozumiem to co wyjaśniasz a w przykładzie wygląda to inaczej niż powinno w stosunku do tego co sam tłumaczysz.

    Jako poczatkujacy javascriptowiec moge powiedziec ze w co 2 przykladzie sa bledy. Prosze popraw to. Bo wprowadzaja w blad osobe uczaca sie

    Odpowiedz

Dyskusja

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *