Închiderea ( eng. closure ) în programare este o funcție de primă clasă , în corpul căreia există referințe la variabile declarate în afara corpului acestei funcții în codul înconjurător și care nu sunt parametrii acesteia. Într-o altă limbă, o închidere este o funcție care se referă la variabile libere din domeniul său .
O închidere, ca o instanță de obiect , este o modalitate de a reprezenta funcționalitatea și datele legate și împachetate împreună.
O închidere este un tip special de funcție. Este definită în corpul unei alte funcții și este creată de fiecare dată când este executată. Sintactic, aceasta arată ca o funcție care se află în întregime în corpul unei alte funcții. În acest caz, funcția interioară imbricată conține referințe la variabilele locale ale funcției exterioare. De fiecare dată când funcția exterioară este executată, este creată o nouă instanță a funcției interioare, cu noi referințe la variabilele funcției exterioare.
În cazul unei închideri, referințele la variabile dintr-o funcție exterioară sunt valabile în interiorul funcției imbricate atâta timp cât funcția imbricată rulează , chiar dacă funcția exterioară a terminat de rulat și variabilele au ieșit din domeniul de aplicare. [unu]
O închidere leagă codul unei funcții de mediul ei lexical (locul în care este definită în cod). Variabilele de închidere lexicale diferă de variabilele globale prin faptul că nu ocupă spațiul de nume global. Ele diferă de variabilele din obiecte prin faptul că sunt legate de funcții, nu de obiecte.
Consultați wikibook pentru mai multe exemple.
Același cod în versiunea ECMAScript2015 folosind „funcții săgeți”:
„utilizați strict” ; const add = x => y => { const z = x + y ; consola . log ( x + '+' + y + '=' + z ); întoarce z ; }; const res = add ( 3 )( 6 ); // returnează 9 și imprimă 3+6=9 în consolă consola . jurnal ( res );Explicație: în JavaScript, combinația => este un operator de declarare a funcției săgeată, vezi de exemplu https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions . Aici constanta add este plasată o funcție a argumentului x , al cărei rezultat va fi o altă funcție, și anume funcția argumentului y , al cărei rezultat este calculat de blocul de cod dat între paranteze. Acest bloc de cod se bazează pe argumentul y al funcției sale și pe o închidere care este creată pe argumentul x al funcției externe.
Când se apelează add(3)(6) , funcția stocată în variabila add este apelată cu un argument de 3 și returnează funcția legată la valoarea 3 din închiderea lui x .
Mai mult, în cadrul unui astfel de apel, această funcție este executată cu un argument y = 6 și returnează 9 .
Puteți face o închidere recursivă :
„utilizați strict” ; const add = x => y => { const z = x + y ; consola . log ( x + '+' + y + '=' + z ); returnează adăuga ( z ); }; const res = add ( 1 )( 4 )( 6 )( 9 ); consola . jurnal ( res ); /* 1+4=5 5+6=11 11+9=20 [Funcție]*/Când codul JS rulează, variabilele locale sunt stocate în domeniu. În JavaScript, variabilele locale pot rămâne în memorie chiar și după ce funcția a returnat o valoare.
Toate funcțiile din JavaScript sunt închideri, adică ori de câte ori este creată o funcție, o închidere este întotdeauna creată, deși este adesea goală, deoarece funcțiile de obicei nu folosesc nimic din declarația contextului. Dar trebuie să înțelegeți diferența dintre crearea unei închideri și crearea unui nou obiect de domeniu: o închidere (funcție + referință la lanțul de domeniu curent) este creată atunci când funcția este definită, dar este creat un nou obiect de domeniu (și utilizat pentru a modifica lanțul domeniului de aplicare al închiderii) de fiecare dată când apelează funcția.
În PHP, închiderile sunt funcții anonime , constructe speciale care vă permit să descrieți funcții care nu au nume specifice.
<?php function add ( $x ) { return function ( $y ) use ( $x ) { // <-- function (închidere) anonima return $x + $y ; }; // <-- acest punct și virgulă este necesar aici! } ecou adaugă ( 3 ) ( 5 ) . PHP_EOL ; // Ieșire: 8 $f = adaugă ( 3 ); var_dump ( $f ); // Ieșire: obiect(Închidere) echo $f ( 6 ) . PHP_EOL ; // Ieșire: 9În PHP, variabilele sunt moștenite din domeniul părinte folosind constructul use prin specificarea explicită a numelor variabilelor moștenite.
Un alt exemplu de trecere a unei închideri la o metodă în care este așteptat un parametru apelabil:
<?php function power ( $arr , $exp ) { // $func va stoca o referinta la obiectul Closure care descrie inchiderea noastra $func = function ( $el ) use ( $exp ) { return $el ** $exp ; }; return array_map ( $func , $arr ); } $listă = [ 1 , 3 , 4 ]; var_dump ( putere ( $list , 2 )); // Ieșire: array(3) {[0]=>int(1) [1]=>int(9) [2]=>int(16)} var_dump ( putere ( $listă , 3 )); // Ieșire: array(3) {[0]=>int(1) [1]=>int(27) [2]=>int(64)}