Starałbym się wyjaśnić zakres leksykalny w prostym języku angielskim. Życz mi powodzenia
pisząc artykuł o zamykaniu i życiu kilka dni temu. Starałem się wyjaśnić zakres leksykalny w sposób krótki i prosty. Zauważyłem, że artykuł jest coraz większy, więc postanowiłem napisać o zakresie leksykalnym osobno.
w tym artykule postaram się wyjaśnić podstawy zakresu leksykalnego, co to znaczy i podać przykłady, które pomogą Ci zrozumieć, jak to działa w JavaScript. Żadnych gadek…Obiecuję.
Po pierwsze, rozbijmy słowo „zakres leksykalny”.
scope
najpierw porozmawiamy o łatwym: scope.
w języku angielskim scope może oznaczać:
- granicę
- region
- środowisko
lub dowolny inny synonim, o którym możesz pomyśleć.
Czy pamiętasz oglądanie samouczka, w którym instruktor mówi ci, że pewien pomysł/temat wykracza poza zakres filmu?
lub gdy zespół z innego działu pracuje nad projektem i mówisz im, aby dodali funkcję, którą uważasz za fajną, a oni mówią: „to wykracza poza zakres tego projektu”.
myślę, że rozumiesz sens. Scope to po prostu region, w którym coś może działać w określonym czasie.
w informatyce może to oznaczać region, w którym istnieją pewne dane i można uzyskać do nich dostęp. Te dane mogą być czymś w rodzaju zmiennej.
w języku takim jak JavaScript, możemy zdefiniować zakres, tworząc blok za pomocą nawiasów klamrowych: {...}
. Nazywamy to lunetą blokową. Oznacza to, że zmienne zadeklarowane wewnątrz tego bloku mogą być dostępne tylko w tym regionie. Ten region obejmuje wszystko w nim, w tym inne bloki potomne/wewnętrzne utworzone w tym regionie.
innymi słowy ten region tolocal
I jego zmienne nie mogą być dostępne bezpośrednio ze świata zewnętrznego. Można to nazwać zasięgiem lokalnym.
zmienne zadeklarowane wewnątrz funkcji znajdują się w lokalnym zasięgu funkcji.
function doSomething() { let name = "john"; console.log(name)}doSomething(); // Prints 'john'// would produce a Reference error// because name is local to doSomething() function's scopeconsole.log(name);
teraz być może słyszałeś już o global Scope. To środowisko, które nie jest zamknięte w bloku. Każdy kod w Twoim środowisku Javascript ma do niego dostęp. Jest to otwarte środowisko JavaScript. Tak więc poniższy kod powinien działać.
let name = "john"; // In the global scopefunction doSomething() { name = "James" console.log(name); // The function can access the global scope variable 'name'}doSomething(); // Prints "James"console.log(name); // Can access 'name' too
należy zwrócić uwagę na jedną rzecz:
zakres ma dostęp do swojego zakresu nadrzędnego, ale zakres nadrzędny nie ma bezpośredniego dostępu do zmiennych zadeklarowanych w wewnętrznym zakresie.
funkcja ma dostęp doname
, ponieważ funkcja jest zadeklarowana w zasięgu globalnym, aname
istnieje w zasięgu globalnym. Jeśli nazwa została zadeklarowana wewnątrz funkcjidoSomething()
, to kod w globalnym zakresie nie może bezpośrednio zmienić wartościname
, ponieważname
jest lokalny dla funkcji.
wierzę, że dobrze rozumiesz, co oznacza Scope. Oznacza po prostu region lub środowisko, w którym zmienna istnieje i może być dostępna lub modyfikowana.
teraz porozmawiajmy o „leksykalnym”
leksykalnym
aby zrozumieć leksykalny, spójrzmy najpierw na słowo, z którego pochodzi: Leksykon.
Leksykon wywodzi się od łacińskiego słowa: „lexis” co oznacza „słowo”
w prostym języku angielskim:
Leksykon oznacza po prostu słownik. W wyrazach porządkowych oznacza słownictwo języka danej osoby. Jest jak książka, w której przechowywane są znaczenie/definicja słów.
gdy chcesz znaleźć Znaczenie słowa, Przejdź do leksykonu.
nie patrzysz na to, gdzie jest użyte słowo i nie zgadujesz, co ono oznacza i jego treść czy wartość. Zawsze idziesz do leksykonu, gdzie cel słowa jest tworzony i jasno określony.
teraz z tym wyjaśnieniem:
Leksyka oznacza po prostu coś związanego z leksyką. Innymi słowy, oznacza to coś związanego ze słowami lub słownictwem języka danej osoby. Coś związanego z tworzeniem lub definiowaniem słów.
porozmawiajmy o zakresie leksykalnym.
zakres leksykalny
widzieliśmy znaczenie tych dwóch słów w prostym angielskim.
z tą wiedzą zdefiniujmy zakres leksykalny po angielsku:
zakres leksykalny oznacza po prostu, że region, w którym słowo istnieje, jest określony przez to, gdzie zostało zdefiniowane lub utworzone.
inne definicje to:
zakres leksykalny oznacza, że znaczenie/wartość słowa Może być określona tylko przez region / środowisko, w którym zostało utworzone.
zakres leksykalny oznacza, że nie zleca się bezpośrednio znaczenia słowa osobom z regionu, który go używa. Dzieje się tak dlatego, że leksykalny kładzie nacisk na pochodzenie na to, gdzie został stworzony/zdefiniowany.
ok, podam przykład.
użyjmy słowa: „Taniec”.
słowo „taniec” zostało stworzone/zdefiniowane w Wielkiej Brytanii . Brytyjczycy znają jego znaczenie. Słowo to istnieje w zakresie, w jakim zostało stworzone: „Wielka Brytania”. Walia jest w Wielkiej Brytanii, więc Walia ma dostęp do tego słowa (pamiętajmy, że wyjaśniliśmy już dlaczego powyżej). Tak więc Walijczycy mogą zaktualizować znaczenie tego słowa, aby pasowało do ich lokalnego dialektu. Dzieje się tak dlatego, że znajdują się one w zasięgu Wielkiej Brytanii.
Niemcy nie mogÄ … bezpoĹ „rednio przyjĺ” Ä ‡ i zmieniÄ ‡ znaczenia tego sĹ ’ owa. To dlatego, że słowo nie zostało stworzone w Niemczech. Tak więc, gdyby Niemcy chcieli użyć angielskiego słowa: „dance”, a to słowo nie zostało jeszcze stworzone przez Wielką Brytanię, to słowo nie byłoby dostępne bez względu na to, jak bardzo się starają. To sprawi, że nikt nie będzie znał prawdziwego znaczenia tego słowa w Niemczech, ponieważ słowo to nie istnieje w brytyjskim Leksykonie. (Nie martw się, jeśli to wydaje się bełkot, wyjaśnię kod później)
ponieważ jesteśmy studentami nauk ścisłych, a nie lingwistów, zastąpmy „słowo” „zmienną”.
nasza nowa definicja byłaby:
zakres leksykalny oznacza po prostu, że obszar, w którym istnieje zmienna, jest określony przez to, gdzie została zdefiniowana lub utworzona.
zakres leksykalny oznacza, że znaczenie/wartość zmiennej może być określona tylko przez region/środowisko, w którym została utworzona.
zakres leksykalny oznacza, że nie zleca się bezpośrednio znaczenia zmiennej do kodu z zewnętrznego regionu(bloku), który używa zmiennej. Dzieje się tak dlatego, że leksykalny kładzie nacisk na pochodzenie na to, gdzie zmienna została utworzona/zdefiniowana.
więc zakres leksykalny pokazuje nam, że zmienna może być używana tylko w zakresie, w którym została utworzona, a nie tam, gdzie została wywołana.
zobaczmy, jak to działa w kodzie:
function rideBritishBoat() { let boatName = "Queen's Dab"; // local variable return `Driving ${boatName}`}function rideGermanBoat() { const status = rideBritishBoat(); return status;}rideGermanBoat();
powyższy przykład symuluje scenariusz, w którym Niemcy kupili łódź z Wielkiej Brytanii….(Możesz zamienić go, który kiedykolwiek kraj Ciebie want…no muszę walczyć, dlaczego nie wspomniałem o innym kraju. To są tylko nazwy krajów, a nie biblioteki JavaScript 😛 ).rideGermanBoat()
używarideBritishBoat()
.
ponieważ JavaScript używa zakresu leksykalnego, podczas wykonywania funkcjirideBritishBoat()
, przechodzi do miejsca, w którym została utworzona i otrzymuje odniesienie do zmiennej:boatName
. Tak więc przy skalowaniu leksykalnym, gdyrideBritishBoat()
jest wykonywany, JavaScript wchodzi do zakresu funkcji, aby szukać zmiennych używanych w tej funkcji.
Uwaga: zakres funkcjirideBritishBoat()
jest jej zakresem lokalnym i globalnym. FunkcjarideGermanBoat()
nie znajduje się w zakresie leksykalnym funkcjirideBritishBoat()
, ponieważrideBritishBoat()
nie została utworzona wewnątrz niej.
teraz zmienimy nieco przykład:
function rideBritishBoat() { return `Driving ${boatName}`; // Reference Error: boatName not defined}function rideGermanBoat() { let boatName = "Merkel's Dab"; const status = rideBritishBoat(); return status;}rideGermanBoat();
powyższy kod nie powiedzie się. FunkcjerideBritishBoat()
nie są precyzyjne. Nie powiedzie się podczas próby uzyskania dostępu do boatName
w instrukcji return.
Dlaczego?
dzieje się tak dlatego, że JavaScript używa zakresu leksykalnego.
Jak to działa, gdy napotka zmiennąboatName
wewnątrz funkcjirideBritishBoat()
, szuka miejsca, w którym zmiennaboatName
została utworzona w łańcuchu zakresu. Oznacza to, że cały możliwy zakres tej funkcji, który jest: lokalnym zakresem funkcji, a następnie sprawdza jej zakres zamykający w tym przypadku zakres Globalny.
tak JavaScript sprawdza zmienne. Najpierw sprawdza blok lokalny, w którym używana jest bieżąca zmienna, aby wiedzieć, czy została tam zadeklarowana. Jeśli nie, to idzie do otaczającego zakresu i kontynuuje, jeśli nie znajdzie deklaracji, dopóki nie osiągnie szczytu łańcucha, który jest globalnym zakresem
istnieje jeszcze jeden rodzaj zakresu zwany „dynamicznym zakresem”.
poprzedni kod będzie działał w języku obsługującym dynamiczne zakresy(np. Lisp).
dzieje się tak dlatego, że w dynamicznie skalowanym środowisku zmienna jest sprawdzana w czasie pracy. Oznacza to, że gdy wykonasz rideGermanBoat()
I WYKONANIE trafi do rideBritishBoat()
środowisko uruchomieniowe sprawdza wartość boatName
, gdzie kod jest aktualnie uruchomiony. W tym przypadku go znajdzie, więc nie ma problemu i Kod działa w oczekiwaniu i wypisuje Driving Merkel's Dab
.
zakres leksykalny nazywany jest również zakresem statycznym, ponieważ jego zakres jest ustalany w czasie kompilacji. Oznacza to, że jego środowisko / zakres jest stały i nie można go po prostu zmienić. Innymi słowy, zmienne mogą być wywoływane tylko z bloku kodu, w którym zostały zadeklarowane/utworzone.
dynamiczny zakres jest nazywany dynamicznym, ponieważ jego środowisko (zewnętrzny zakres) może się zmieniać. Innymi słowy, zmienne mogą być wywoływane spoza bloku, w którym są tworzone.
więc możemy mieć inną funkcję, która używarideBritishBoat()
o nazwie rideMauritianBoat()
:
function rideMauritianBoat() { let boatName = "Flying Dodo's Dab"; const status = rideBritishBoat(); return status;}rideMauritianBoat();
w dynamicznie skalowanym języku można zobaczyć wartość zmiennejboatName
wewnątrz zmiennejrideBritishBoat()
jest zależna od zakresu, w którym jest wykonywana. Jak widzimy, zakres ten może się zmieniać, stąd jest dynamiczny.
więc wewnątrzrideBritishBoat()
, wywołujeboatName
zmiennąrideMauritianBoat()
, która znajduje się poza jej zakresem bloku.
To jest Scoping dynamiczny, a Scoping leksykalny jest odwrotnie.
ale pamiętaj, JavaScript nie jest dynamicznie skalowany. To tylko po to, by pokazać Ci różnicę.
tak więc leksykalne sprawdzanie zakresu dla zmiennych w czasie kompilacji (zmienne muszą być wytworzone i dostępne w obszarze/bloku, w którym są używane) podczas dynamiczne sprawdzanie zakresu dla zmiennych w czasie wykonywania (zmienne mogą nie być tworzone w zakresie podczas kompilacji, ale mogą być obecne podczas działania funkcji).
Senior Devs be like: Dude!! JavaScript nie jest językiem skompilowanym!!
Proszę, zostawmy tę rozmowę na inny dzień. Postaraj się dotrzeć do wiadomości, którą przekazuję.
dobra, jestem teraz wkurzony. Oto ćwiczenie dla Ciebie.
szybkie ćwiczenie
Jakie będzie wyjście tej funkcji?
function rideBritishBoat() { let boatName = "Queen's Dab"; function rideWelshBoat() { boatName = "Welsh Royal Boat"; console.log(boatName) } rideWelshBoat();}rideBritishBoat()
Streszczenie
celem artykułu było wyjaśnienie zakresu leksykalnego w prosty sposób z wykorzystaniem podstawowych gramatyk i krótkich przykładów. Jeśli zauważyłeś, że niektóre słowa są pogrubione. Są to kluczowe słowa, aby zrozumieć tę koncepcję. Dodatkowo, mam wiele alternatywnych definicji tych samych pojęć. Zostało to zrobione, aby wybrać, który z nich łatwo się dla ciebie zlewa. Różne uderzenia dla różnych ludzi 😉
z tego, czego dowiedzieliśmy się powyżej, możemy powiedzieć, że:
- zakres jest środowiskiem/regionem, w którym coś (zmienna) istnieje
- zakres może uzyskać dostęp do swoich rodziców.
- zakres nadrzędny nie ma bezpośredniego dostępu do zmiennych zadeklarowanych w wewnętrznym zakresie.
- leksykalne ma do czynienia z tym, gdzie zmienna została zadeklarowana / utworzona.
- zakres leksykalny wymusza znalezienie zmiennych z zakresu/bloku, w którym zostały utworzone / zadeklarowane, a nie Środowiska, w którym są uruchomione.
- zakres dynamiczny jest przeciwieństwem zakresu leksykalnego.
- dynamiczne zakresy sprawdzają zmienne, z których są uruchomione.
dzięki za przeczytanie.
Do zobaczenia w następnym poście.