JavaScript - funkcje, przestrzeń nazw
Funkcje
Deklaracja funkcji
Poniższa funkcja zostaje wyniesiona zanim program wystartuje. Dzięki temu jest dostępna wszędzie w ramach zasięgu, w którym została zadeklarowana, nawet, jeżeli ta funkcja została wywołana przed faktyczną definicją w kodzie źródłowym.
foo(); // Działa ponieważ definicja funkcji została wyniesiona
// na początek zasięgu przed uruchomieniem kodu
function foo() {}
Wyrażenie funkcyjne
Ze względu na hoisting, deklaracja var
wynosi zmienną foo
na początek zasięgu zanim kod zostanie faktycznie uruchomiony, ale przypisania wartości robione są dopiero podczas wykonywania, wartość foo
będzie ustawiona na domyślną wartość undefined
zanim poniższy kod zostanie uruchomiony.
foo; // 'undefined'
foo(); // wyrzuca błąd TypeError
var foo = function() {};
Przestrzeń nazw
Zaleca się, aby zawsze używać anonimowych wrapperów (inaczej: Immediately-Invoked Function Expression - IIFE) do hermetyzacji kodu wewnątrz jego własnej przestrzeni nazw. To nie tylko chroni kod przed kolizją nazw, ale również wprowadza lepszą modularyzację programów.
(function() {
// autonomiczna "przestrzeń nazw"
window.foo = function() {
// wyeksponowane domkniecie (closure)
};
})(); // natychmiastowe wykonanie funkcji
Komentarz do powyższego kodu.
( // zewaluowanie funkcji znajdującej się wewnątrz nawiasów
function() {}
) // zwrócenie obiektu funkcji
() // wywołanie rezultatu ewaluacji
Warto sprawdzić wzorzec modułu na stronie JS - obiekty.
Jak działa this
Częste pułapki - domknięcia i that
Powszechnym błędem jest myślenie, że this
wewnątrz test
wskazuje na Foo
, podczas gdy w rzeczywistości tak nie jest.
Foo.method = function() {
function test() {
// wewnątrz tej funkcji this wskazuje na obiekt global
}
test();
}
Aby uzyskać dostęp do Foo
wewnątrz test
, niezbędne jest stworzenie wewnątrz metody lokalnej zmiennej, która będzie wskazywała na Foo
.
that
jest zwykłą zmienną, ale jest to powszechnie stosowana konwencja otrzymywania wartości zewnętrznego this
. W połączeniu z domknięciami(closures), jest to sposób na przekazywanie wartości this
wokół.
Foo.method = function() {
var that = this;
function test() {
// Należy używać that zamiast this wewnątrz tej funkcji
}
test();
}
Kontekst this
function foo() {
console.log(this);
}
foo(); // logs out the global e.g. `window` in browsers
let bar = {
foo
}
bar.foo(); // Logs out `bar` as `foo` was called on `bar`
Źródło