Godzina 3 (dziś): co widzi funkcja - zmienne lokalne
Godzina 4: parseFloat, Math - powtórka
Rozgrzewka · 3 minuty
Rozgrzewka: funkcje z poprzedniej lekcji
Jaki atrybut znacznika <button> wywołuje waszą funkcję po kliknięciu?
Do czego służy document.getElementById("number1").value wewnątrz funkcji add()?
Dlaczego funkcja absoluteValue(number) daje wynik 7 zarówno dla -7, jak i dla 7?
Część 1 · Zasięg zmiennej
Dwa zamknięte „pokoje”
Tak jak w PHP, zmienna zadeklarowana let albo var wewnątrz funkcji istnieje tylko w jej „pokoju”. Kod na zewnątrz funkcji - poza parametrem (wejście) i return (wyjście) - jej nie widzi.
MDN: Learn_web_development/Core/Scripting/Functions, sekcja „Function scope and conflicts” („The top-level outside all your functions is called the global scope. Values defined in the global scope are accessible from everywhere in the code.” - tłum. własne: „Najwyższy poziom, poza wszystkimi funkcjami, nazywa się zasięgiem globalnym. Wartości zdefiniowane w zasięgu globalnym są dostępne z każdego miejsca kodu.”) oraz to samo źródło, porównanie z apartamentowcem: „Each apartment is private to the people who live there, similar to function scope... The building also may have common areas... This is like the global scope.” - tłum. własne: „Każde mieszkanie jest prywatne dla osób, które w nim mieszkają, podobnie jak zasięg funkcji... Budynek może też mieć części wspólne... To jest jak zasięg globalny.”
Część 2 · Zmienna z pętli for
let i w pętli: zamknięte w funkcji
functionfun1(a) {
for (let i = 1; i < 6; i++) {
console.log(i * a);
}
}
fun1(2);
console.log(i); // poza funkcją
W konsoli:fun1(2) wypisuje kolejno 2 4 6 8 10. Linia console.log(i); po wywołaniu funkcji rzuca Uncaught ReferenceError: i is not defined - i istniało tylko w czasie działania fun1.
MDN: Learn_web_development/Core/Scripting/Functions, sekcja „Function scope and conflicts” („When you create a function, the variables and other things defined inside the function are inside their own separate scope. This means that they are locked away in their own separate compartment, unreachable from code outside the function.” - tłum. własne: „Gdy tworzysz funkcję, zmienne i inne rzeczy zdefiniowane wewnątrz niej znajdują się w swoim własnym, oddzielnym zasięgu. Są zamknięte w swoim własnym, oddzielnym pomieszczeniu, nieosiągalnym z kodu na zewnątrz funkcji.”)
Część 3 · Bez let ani var
Zmienna bez let/var„wycieka” na zewnątrz
functionfun1(a) {
for (n = 1; n < 6; n++) {
console.log(n * a);
}
}
fun1(2);
console.log(n); // 6 - n istnieje na zewnątrz!
Ciekawostka z MDN: dokładnie ten błąd (literówka w nazwie zmiennej bez let) potrafił latami psuć duże programy, bo silnik JavaScript zawsze zgadzał się cicho utworzyć nową zmienną globalną. Tryb "use strict" to zmienia: przypisanie do niezadeklarowanej zmiennej od razu rzuca błąd, zamiast pozwolić kodowi „działać” dalej z ukrytym błędem.
Ten sam wzorzec (zmienna n bez var/let) pojawia się w zadaniu CKE E.14 czerwiec 2016 zad. 31, slajd „Tak pytają na egzaminie” · MDN, „Strict mode”, sekcja „Converting mistakes into errors”: „Strict mode makes it impossible to accidentally create global variables.” - tłum. własne: „Tryb ścisły uniemożliwia przypadkowe tworzenie zmiennych globalnych.”
Część 4 · Ta sama nazwa, dwie zmienne
Dwie funkcje, ta sama nazwa zmiennej - brak konfliktu
functionshowMessage() { let total = 5; console.log(total); }
functioncountGuests() { let total = 100; console.log(total); }
showMessage(); // 5countGuests(); // 100
MDN: Learn_web_development/Core/Scripting/Functions, sekcja „Function scope and conflicts” - przykład z dwoma niezależnymi plikami, które definiują zmienną i funkcję o tej samej nazwie, ilustruje ten sam mechanizm zamykania zmiennych w osobnym zasięgu („Locking parts of your code away in functions avoids such problems and is considered a best practice.” - tłum. własne: „Zamykanie fragmentów kodu wewnątrz funkcji unika takich problemów i jest uznawane za dobrą praktykę.”)
Egzamin E.14
Tak pytają na egzaminie
1.
Dla dowolnego a z przedziału (0, 99) zadaniem funkcji zapisanej w języku JavaScript jest
function fun1(a) {
for (n = a; n <= 100; n++)
document.write(n);
return n;
}
zwrócenie liczb z przedziału a .. 99
wypisanie liczb z przedziału a .. 99 i zwrócenie wartości 100
wypisanie wartości zmiennej a oraz zwrócenie wartości zmiennej n
wypisanie liczb z przedziału a .. 100 i zwrócenie wartości zmiennej n
2.
Jakie elementy wypisze funkcja printItems(2) stworzona w języku JavaScript?
CKE, E.14, czerwiec 2016, zadanie 31 · CKE, E.14, styczeń 2018, zadanie 34
Ćwiczenie przy komputerze · 25 minut
Ćwiczenie: co widzi fun1
W swoim script.js z poprzednich lekcji dopisz function fun1(a) { for (let i = 1; i < 6; i++) { console.log(i * a); } }.
Wywołaj fun1(2) i sprawdźcie w konsoli (F12) pięć wypisanych wyników.
Zaraz pod wywołaniem dopiszcie console.log(i); - sprawdźcie, że i nie istnieje poza funkcją (Uncaught ReferenceError). Usuńcie tę linię po sprawdzeniu.
Skopiujcie funkcję jako fun1NoLet i w pętli usuńcie słowo let przed i. Wywołajcie ją i sprawdźcie, że tym razem console.log(i); poza funkcją DZIAŁA - i „wyciekło” na zewnątrz.
Dla chętnych w domu: wywołaj fun1(3) i sprawdź, czy poza funkcją nadal nie widać i.
Na koniec
Sprawdź się
Dlaczego zmienna zadeklarowana let wewnątrz funkcji nie istnieje poza nią?
Co się stanie, gdy w funkcji przypiszecie wartość zmiennej bez let ani var?
Dlaczego dwie różne funkcje mogą mieć zmienną o tej samej nazwie bez konfliktu?
To tyle na dziś - kolejny temat: parseFloat i Math, powtórka funkcji.
Poza szkołą
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
let wewnątrz funkcji widoczne tylko lokalnie
Ten sam mechanizm w każdej funkcji JS; moduły ES dodatkowo izolują cały plik.
nadal w użyciu
Zmienna bez let/var tworząca zmienną globalną (wyciek)
"use strict" (domyślne w modułach ES) zamienia to w błąd zamiast cichego wycieku.
zastępowane
Dwie funkcje z tą samą nazwą zmiennej lokalnej
Ten sam wzorzec pozwala pisać niezależne funkcje bez uzgadniania nazw zmiennych w całym projekcie.
nadal w użyciu
MDN: Learn_web_development/Core/Scripting/Functions, sekcja „Function scope and conflicts” („JavaScript works like this mainly for security and organization. Sometimes you don't want variables to be accessible from everywhere in the code... This might be done maliciously or just by accident.” - tłum. własne: „JavaScript działa tak głównie ze względów bezpieczeństwa i organizacji. Czasem nie chcecie, żeby zmienne były dostępne z każdego miejsca kodu... Może się to zdarzyć złośliwie albo przez przypadek.”)