Closure ( eng. closure ) i programmering är en förstklassig funktion , i vars brödtext det finns referenser till variabler som deklareras utanför kroppen av denna funktion i den omgivande koden och som inte är dess parametrar. På ett annat språk är en stängning en funktion som refererar till fria variabler i dess omfattning .
En stängning, som en objektinstans , är ett sätt att representera funktionalitet och data bundna och paketerade tillsammans.
En stängning är en speciell typ av funktion. Den definieras i kroppen för en annan funktion och skapas varje gång den exekveras. Syntaktiskt ser detta ut som en funktion som är helt och hållet i kroppen av en annan funktion. I det här fallet innehåller den kapslade inre funktionen referenser till de lokala variablerna för den yttre funktionen. Varje gång den yttre funktionen exekveras skapas en ny instans av den inre funktionen, med nya referenser till variablerna för den yttre funktionen.
I fallet med en stängning är referenser till variabler i en yttre funktion giltiga inuti den kapslade funktionen så länge den kapslade funktionen körs , även om den yttre funktionen har körts färdigt och variablerna har gått utanför räckvidden. [ett]
En stängning länkar koden för en funktion till dess lexikala miljö (den plats där den definieras i koden). Lexikaliska stängningsvariabler skiljer sig från globala variabler genom att de inte upptar den globala namnrymden. De skiljer sig från variabler i objekt genom att de är bundna till funktioner, inte objekt.
Se wikiboken för fler exempel.
Samma kod i ECMAScript2015-versionen med "pilfunktioner":
'använd strikt' ; const add = x => y => { const z = x + y ; konsol . log ( x + '+' + y + '=' + z ); returnera z ; }; const res = addera ( 3 )( 6 ); // returnerar 9 och skriver ut 3+6=9 till konsolen konsol . log ( res );Förklaring: i JavaScript är kombinationen => en pilfunktionsdeklarationsoperator, se till exempel https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions . Här placeras den konstanta adderingen en funktion av argumentet x , vars resultat blir en annan funktion, nämligen funktionen av argumentet y , vars resultat beräknas av kodblocket inom parentes. Detta kodblock förlitar sig på y -argumentet för dess funktion och på en stängning som skapas på x -argumentet för den yttre funktionen.
När add(3)(6) anropas anropas funktionen som är lagrad i variabeln add med argumentet 3 och returnerar funktionen bunden till värdet 3 i x 's closure .
Vidare, inom ramen för ett sådant anrop, exekveras denna funktion med ett argument y = 6 och returnerar 9 .
Du kan göra en rekursiv stängning:
'använd strikt' ; const add = x => y => { const z = x + y ; konsol . log ( x + '+' + y + '=' + z ); returnera add ( z ); }; const res = addera ( 1 )( 4 )( 6 )( 9 ); konsol . log ( res ); /* 1+4=5 5+6=11 11+9=20 [Funktion]*/När JS-koden körs lagras lokala variabler i scope. I JavaScript kan lokala variabler finnas kvar i minnet även efter att funktionen har returnerat ett värde.
Alla funktioner i JavaScript är stängningar, det vill säga när en funktion skapas skapas alltid en stängning, även om den ofta är tom, eftersom funktioner vanligtvis inte använder något från kontextdeklarationen. Men du måste förstå skillnaden mellan att skapa en stängning och att skapa ett nytt scope-objekt: en stängning (funktion + referens till den aktuella scope-kedjan) skapas när funktionen definieras, men ett nytt scope-objekt skapas (och används för att ändra stängningens omfattningskedja) varje gång funktionsanrop.
I PHP är stängningar anonyma funktioner , speciella konstruktioner som låter dig beskriva funktioner som inte har specifika namn.
<?php function add ( $x ) { return function ( $y ) use ( $x ) { // <-- anonym funktion (closure) return $x + $y ; }; // <-- detta semikolon behövs här! } echo add ( 3 ) ( 5 ) . PHP_EOL ; // Utdata: 8 $f = lägg till ( 3 ); var_dump ( $f ); // Output: object(Closure) echo $f ( 6 ) . PHP_EOL ; // Utdata: 9I PHP ärvs variabler från det överordnade omfånget med användningskonstruktionen genom att explicit specificera namnen på de ärvda variablerna.
Ett annat exempel på att skicka en stängning till en metod där en anropsbar parameter förväntas:
<?php function power ( $arr , $exp ) { // $func kommer att lagra en referens till Closure-objektet som beskriver vår stängning $func = function ( $el ) use ( $exp ) { retur $el ** $exp ; }; returnera array_map ( $func , $arr ); } $list = [ 1 , 3 , 4 ]; var_dump ( power ( $list , 2 )); // Output: array(3) {[0]=>int(1) [1]=>int(9) [2]=>int(16)} var_dump ( power ( $list , 3 )); // Utdata: array(3) {[0]=>int(1) [1]=>int(27) [2]=>int(64)}