Circuit - această legătură funcție de variabilele independente (gratuit). Cu alte cuvinte, funcția definită în închidere, „își amintește“ mediul în care a fost creat.
domeniul de aplicare lexical
Luați în considerare următorul exemplu:
Funcția de inițializare () creează un nume de variabilă locală. și apoi solicită funcția displayName (). displayName () - este o funcție internă - acesta este definit în cadrul init () și este disponibil numai în corpul funcției. Spre deosebire de inițializare (). displayName () nu are variabile locale și folosește în schimb un nume de variabilă. anumite funcții în părinte.
Luați în considerare următorul exemplu:
Într-un caz simplu, variabilele locale în funcții există doar în momentul executării sale. După apelarea makeFunc () poate fi de așteptat ca numele variabilei nu va mai fi disponibilă. Acest lucru nu este, evident, închiderea caz.
Soluția la acest puzzle, care a devenit închidere myFunc. Circuit - este un tip special de obiect care combină două lucruri: funcția și mediul în care a fost creat funcția. Stabilirea unui membru al oricărei variabile locale, care a fost în domeniul de aplicare al funcțiilor la momentul creării circuitului. În acest caz, myFunc - acest circuit, care conține funcția displayName. și șirul „Mozilla“, care a existat în timpul creării circuitului.
Iată un exemplu mai interesant - funcția makeAdder:
Aici am identificat funcția makeAdder (x). care primește x. și returnează o nouă funcție. Această funcție ia y. și returnează suma lui x și y.
În esență, această funcție makeAdder fabrică - creează o funcție care poate adăuga valori specifice pentru argumentele sale. În exemplul de mai sus, vom folosi funcția noastră fabrică pentru a crea două noi funcții - o definește ca argument la o valoare de 5, al doilea - 10.
add5 și add10 - acestea sunt exemple de circuite. Corpul funcției este aceeași, dar ele păstrează medii diferite. Inconjurat add5 x funcție - 5, în timp ce înconjurat de add10 x - este 10.
Închideri în practică
Totul e bine, dar, în măsura în care circuitul util în practică? Să vedem ce se poate face cu ele. În general, închiderea vă permite să asociați unele date (un mediu specific) cu o funcție care lucrează cu aceste date. paralele evidente cu programarea orientată pe obiecte, un obiect care ne permite să se refere setul de date (proprietăți obiect) cu una sau mai multe metode.
Adică, circuitul poate fi folosit oriunde, în cazul în care ar fi normal și corect utilizarea unui obiect cu o singură metodă.
Să ne uităm la un exemplu practic: Să presupunem că vrem să adăugați la pagina de câteva butoane care se va schimba dimensiunea textului. Alternativ, putem specifica proprietatea font-size pe elementul de corp în pixeli, iar apoi setați dimensiunea celorlalte elemente ale paginii (cum ar fi titluri, de exemplu), folosind unități relative em:
Apoi, butoanele noastre se vor schimba proprietatea font-size a elementului de corp, precum și celelalte elemente ale paginii doar pentru a ridica noua valoare și scala dimensiunea textului prin utilizarea unităților relative.
Acum size12. size14. și size16 - sunt funcții care schimba dimensiunea textului din elementul de corp la valorile de 12, 14 și 16 pixeli, respectiv. După aceea, ne agățăm de aceste funcții, butoane, cum ar fi acest lucru:
Metodele private Imită prin circuite
Limbaje ca Java ne permit să declare metode private. Acest lucru este atunci când acestea pot apela doar alte metode de aceeași clasă, dar ele nu sunt accesibile din exterior.
Iată cum puteți descrie circuitele prin utilizarea mai multor metode publice care au acces la metode private și variabile. Acest stil de programare este numit, de asemenea, modelul modulului. în traducere română stabilit încă nu, dar puteți folosi cuvântul de căutare „modul“, „șablon“ și „Javacript“:
Există o mulțime de lucruri schimbat. În exemplul anterior, fiecare circuit a avut contextul său propriu de execuție (mediu). Aici vom crea un mediu unificat pentru trei funcții: Counter.increment. Counter.decrement. și Counter.value.
Un singur mediu este creat în corpul unei funcții anonime care se execută în momentul dezvăluirii. Acest mediu include un privat două elemente: variabilă și privateCounter fuktsii changeBy. Nici unul dintre aceste elemente sunt disponibile în mod direct în afara funcției anonim în sine. În schimb, ei pot și ar trebui să fie utilizate trei funcții publice, care returnează un bloc anonim cod (înveliș anonim), efectuate în aceeași funcție anonimă.
Notă, descriem o funcție anonimă a cererii care creează contorul, și apoi executați prin atribuirea rezultatului executării Contrareformei variabile. Dar noi, de asemenea, nu poate rula această funcție o dată, și păstrați-l într-o variabilă separată pentru a utiliza pentru a favoriza crearea de câțiva metri, cum ar fi acest lucru:
Rețineți că contoarele funcționează independent unul de celălalt. Acest lucru se datorează faptului că fiecare dintre ele în momentul în care makeCounter funcția () a fost creat ca un context de execuție separat (mediu). Aceasta este o variabilă privateCounter privată în fiecare contor este de fapt o variabilă independentă separată.
Utilizarea circuitului în acest fel, veți obține o serie de avantaje asociate în mod normal cu programarea orientată pe obiecte, cum ar fi izolarea și încapsulare.
Crearea de închidere în ciclul: O greșeală foarte frecvente.
Înainte de versiunea ECMAScript 6 introdus cuvântul cheie lasa. în mod constant ca urmare apar probleme la crearea circuitelor în interiorul buclei. Luați în considerare următorul exemplu:
Array helpText descrie trei sfaturi pentru cele trei domenii de intrare. Ciclul trece prin descrierile coadă și pentru fiecare dintre câmpurile de intrare specifică faptul că atunci când are loc un eveniment onfocus pentru acest element ar trebui să fie numit în funcție de afișarea prompt corespunzătoare.
Dacă executați acest cod, veți vedea că nu funcționează modul în care ne-am dorit. Care câmp nu ar fi ales, ca un ghid va fi întotdeauna afișat un mesaj despre vârstă.
Problema este că funcțiile atribuite atât Stivuitoare eveniment onfocus, sunt închiderile. Ele constau dintr-o descriere a funcției și a contextului de execuție (mediu), moștenit de la funcția setupHelp. A fost creat trei circuite, dar toate au fost create cu același context de execuție (mediu). Până în momentul în care a avut loc evenimentul ciclu onfocus a fost mult timp îndeplinite și, prin urmare, elementul variabil (aceeași pentru toate cele trei circuite) indică ultimul element al matrice, care este doar despre câmpul de vârstă.
Ca o soluție, în acest caz, putem sugera utilizarea funcțiilor, funcția de fabrică (fabrică funcția), așa cum a fost descris mai sus în exemplele:
Aici funcționează așa cum trebuie. În loc de partajare un singur mediu, la toate, funcția makeHelpCallback creează fiecare închiderilor proprii, în care punctele de variabile la elementul corect helpText element de matrice.
Considerații privind performanța
Nu este nevoie să fără a fi nevoie de a crea o funcție într-o funcție în cazurile în care nu este nevoie de circuit. Folosind această tehnică crește cerințele de performanță, atât în ceea ce privește viteza cât și în ceea ce privește consumul de memorie.
Ca un exemplu, atunci când se creează un nou obiect / clasă, are sens pentru a pune toate metodele în prototipul obiectului, mai degrabă decât să le descrie în designer de text. Faptul este că, dacă se face în mod diferit, de fiecare dată când este creat un obiect pentru aceasta va crea o copie a fiecărei metode, în loc să le moștenind de prototip.
Să ne uităm nu este foarte practic, dar spune exemplu:
Deoarece codul de mai sus nu profita de circuite, acesta poate fi rescrisă după cum urmează:
Metodele livrate într-un prototip. Cu toate acestea, suprascrie prototipul -, în sine, este un obicei prost, așa că hai să-l rescrie, astfel încât noi metode sunt pur și simplu adăugate la prototipul existent.
Codul de mai sus se poate face cu mai multă acuratețe, oferind același rezultat:
Vă mulțumim! Vă rugăm să verificați dosarul dvs. „Inbox“ pentru a confirma abonamentul.
Dacă anterior nu a confirmat abonarea la newsletter Mozilla, va trebui să o facă. Vă rugăm să verificați inbox-ul sau spam în căsuța poștală pentru a vedea dacă acesta nu a fost o scrisoare de la noi.
Ascunde abona la newsletter
De ce MDN arată diferit?
MDN se schimbă, concentrându-se doar pe documentația tehnologiilor web. Toate același conținut mare de a rămâne aici; vom schimba doar elementele vizuale și de navigare pentru a vă ajuta să găsiți rapid documentația pentru tehnologia web.
Dar nu vă faceți griji, MDN și Mozilla sunt încă împreună. De fapt, vom actualiza numai proiectarea MDN în mod repetat, pentru a se conforma cu noua emblema și culorile Mozilla.
Cititi mai multe despre reproiectarea în post pe blog-ul nostru. Vă mulțumim pentru utilizarea MDN!
Ascunde mesaj despre reproiectarea