În JavaScript, domeniul de aplicare este contextul în care este executat codul. Există trei tipuri de domeniu de aplicare: domeniul de aplicare global, domeniul de aplicare local (denumit uneori "domeniul de aplicare al funcției") și domeniul de aplicare eval.
Codul definit folosind var
în interiorul unei funcții este specifică local și este "vizibilă" doar pentru alte expresii din această funcție, care include codul în interiorul oricărei funcții imbricate / copil. Variabilele definite în domeniul de aplicare global pot fi accesate de oriunde, deoarece acestea reprezintă cel mai înalt nivel și ultima oprire din lanțul de aplicare.
Examinați codul care urmează și asigurați-vă că înțelegeți că fiecare declarație de foo
este unic datorită domeniului de aplicare.
Mostră: sample110.html
Asigurați-vă că ați înțeles fiecare foo
variabila conține o valoare diferită deoarece fiecare este definită într-un domeniu specific delimitat.
Poate fi creat un număr nelimitat de domenii de funcții și eval, în timp ce un mediu global este utilizat de un mediu JavaScript.
Domeniul de aplicare global este ultima oprire din lanțul de aplicare.
Funcțiile care conțin funcții creează domenii de execuție stivuite. Aceste stive, care sunt înlănțuite împreună, sunt adesea denumite lanț de aplicare.
Deoarece declarațiile logice (dacă
) și declarații looping (pentru
) nu creează un domeniu de aplicare, variabilele se pot suprascrie reciproc. Examinați următorul cod și asigurați-vă că înțelegeți că valoarea lui foo
este redefinit ca programul execută codul.
Mostră: sample111.html
Asa de foo
se modifică pe măsură ce codul se execută, deoarece JavaScript nu are o funcție de blocare a domeniului, globală sau eval.
var
În interiorul funcțiilor de declarare a variabilelor și de evitare a scopului GotchasJavaScript va declara orice variabile lipsesc a var
(chiar și cele conținute într-o funcție sau funcții încapsulate) să se afle în sfera globală de aplicare, în locul scopului local dorit. Aruncați o privire la codul care urmează și observați că fără utilizarea var
pentru a declara o bară, variabila este de fapt definită în domeniul de aplicare global și nu domeniul de aplicare local, unde ar trebui să fie.
Mostră: sample112.html
Conceptul de a lua aici este că ar trebui să utilizați întotdeauna var
când se definesc variabilele din interiorul unei funcții. Acest lucru vă va împiedica să vă ocupați de problemele potențial confuz de aplicare. Excepția la această convenție, desigur, este atunci când doriți să creați sau să modificați proprietăți în domeniul global de aplicare dintr-o funcție.
Există un lanț de căutare care este urmat atunci când JavaScript caută valoarea asociată unei variabile. Acest lanț se bazează pe ierarhia domeniului. În codul care urmează, înregistrez valoarea sayHiText
de la func2
funcție de domeniu.
Mostră: sample113.html
Cum este valoarea lui sayHiText
găsită atunci când nu este cuprinsă în interiorul domeniului de aplicare al directivei func2
funcţie? JavaScript prima arata in func2
funcția pentru o variabilă numită sayHiText
. Nu găsesc func2
acolo, arata func2
funcția parentală, func1
. sayHiText
variabila nu este găsită în func1
domeniul de aplicare, fie, astfel încât JavaScript apoi continuă până la domeniul de aplicare global în cazul în care sayHiText
se găsește, în acest moment valoarea lui sayHiText
a fost livrat. Dacă sayHiText
nu au fost definite în domeniul global, nedefinit
ar fi fost returnat de JavaScript.
Acesta este un concept foarte important de înțeles. Să examinăm un alt exemplu de cod, unul în care luăm trei valori din trei domenii diferite.
Mostră: sample114.html
Valoarea pentru z
este locală la bar
funcția și contextul în care console.log
este invocată. Valoarea pentru y
este in foo
funcția, care este părintele lui bar()
, și valoarea pentru X
este în domeniul de aplicare global. Toate acestea sunt accesibile bar
funcția prin intermediul lanțului de aplicare. Asigurați-vă că înțelegeți că variabilele de referință din bar
funcția va verifica până la capăt lanțul de aplicare pentru variabilele la care se face referire.
Lanțul de aplicare, dacă vă gândiți la el, nu este atât de diferit de lanțul prototip. Ambele sunt pur și simplu o modalitate de a căuta o valoare prin verificarea unui set sistematic și ierarhic de locații.
În proba de cod care urmează, o variabilă numită X
există în același domeniu în care este examinată console.log
. Această valoare "locală" X
este folosit, și s-ar putea spune că acesta este umbre sau măști, numit identic X
variabilele găsite mai sus în lanțul de aplicare.
Mostră: sample115.html
Amintiți-vă că domeniul de căutare se termină atunci când variabila se găsește în cea mai apropiată legătură disponibilă a lanțului, chiar dacă aceeași denumire a variabilei este utilizată mai sus în lanț.
Deoarece funcțiile determină domeniul de aplicare și funcțiile pot fi transmise în jurul valorii de orice valoare JavaScript, s-ar putea crede că descifrarea lanțului de aplicare este complicată. Este de fapt foarte simplu. Lanțul de domeniu este decis în funcție de localizarea unei funcții în timpul definiției, nu în timpul invocării. Acesta este, de asemenea, numit lexical scoping. Gândiți-vă lung și greu despre acest lucru, deoarece majoritatea oamenilor se împiedică adesea în codul JavaScript.
Lanțul de sferă de aplicare este creat înainte de a invoca o funcție. Din acest motiv, putem crea închideri. De exemplu, putem avea o funcție de returnare a unei funcții imbricate în domeniul de aplicare global, totuși funcția noastră poate totuși accesa, prin intermediul lanțului de aplicare, domeniul de aplicare al funcției părinte. În exemplul următor, definim a parentFunction
care returnează o funcție anonimă și numim funcția returnată din domeniul global. Pentru că funcția noastră anonimă a fost definită ca fiind conținută în interiorul parentFunction
, are încă acces la parentFunctions
atunci când este invocată. Aceasta se numește închidere.
Mostră: sample116.html
Ideea pe care ar trebui să o luați aici este că lanțul de sferă de aplicare este determinat în timpul definiției, literalmente, în modul în care este scris codul. Transmiterea funcțiilor din interiorul codului dvs. nu va schimba lanțul de aplicare.
Luați ceea ce ați aflat despre lărgirea domeniului și despre domeniul de aplicare din acest articol și închiderea nu ar trebui să fie prea complicată pentru a înțelege. În următorul exemplu, creăm o funcție numită countUpFromZero
. Această funcție returnează, de fapt, o referință la funcția copil inclusă în ea. Când această funcție a copilului (funcția imbricată) este invocată, ea are încă acces la domeniul de aplicare al funcției părinte din cauza lanțului de domeniu.
Mostră: sample117.html
De fiecare dată countUpFromZero
este invocată funcția anonimă din (și returnată) din countUpFromZero
funcția are încă acces la domeniul funcției părinte. Această tehnică, facilitată prin intermediul lanțului de aplicare, este un exemplu de închidere.
Dacă simți că am închideri prea simplificate, probabil că ai dreptate în acest gând. Dar am făcut așa intenționat, deoarece cred că părțile importante provin dintr-o înțelegere solidă a funcțiilor și a domeniului de aplicare, nu neapărat complexitatea contextului de execuție. Dacă aveți nevoie de o scufundare în profunzime în închideri, aruncați o privire la JavaScript Closures.