Le

Lezárások ebben a kurzusban: JavaScript

1 feladat

A(z) Lezárások fogalomról

A closure-ök egy programozási minta a JavaScriptben, amely lehetővé teszi, hogy egy külső lexikai scope változóit egy egymásba ágyazott kódblokkon belül használjuk. A JavaScript átláthatóan támogatja a closure-öket, és gyakran anélkül használjuk őket, hogy tudnánk, mi is az.

// Top-level declarations are global-scope
const dozen = 12;

// Functions create a new function-scope and block-scope.
// Referencing the outer variable here is a closure.
function nDozen(n) {
  return dozen * n;
}

A closure név történetileg a λ-kalkuluszból származik, és a scheme tette népszerűvé (forrás), hogy egy függvény nyitott és zárt változókötéseire utaljon.

Miért érdemes closure-öket használni a JavaScriptben

  1. Adatvédelem / adatelkapszulázás

    • A többi nyelvvel ellentétben 2020-ban nem volt mód privát változók megadására. A closure-ökkel viszont hatékonyan utánozhatók a privát változók (volt egy javaslat a privát változók jelölésére, ami lehet, hogy mire ezt olvasod, már szabvány lett).
    // Consider this function:
    
    const saveNumber = (number) => {
      // The saved value is unaccessible by the outer lexical scope.
      const value = number;
    
      // We can provide access to the primitive value with a function, but the original will never change
      return () => value;
    };
    
    // Attempting to set the variable outside of its lexical scope results in an error
    value = 42;
    
  2. Részleges alkalmazás

    • A függvények visszaadhatnak függvényeket, és amikor a visszaadott függvény az őt létrehozó függvény argumentumát használja, az példa arra, hogy closure-rel részleges alkalmazást végzünk. Ezt néha a függvény _currying_jének nevezik.
    // The arguments are applied one-by-one, using closures to arrive at the final result
    function partialBuildUri(scheme) {
      return function (domain) {
        return function (path) {
          return `${scheme}://${domain}/${path}`;
        };
      };
    }
    
    // A function could apply them all at once.
    function buildUri(scheme, domain, path) {
      return partialBuildUri(scheme)(domain)(path);
    }
    
    // Or apply a few to create a flexible system of functions for reuse.
    function buildHttpsExercismUri(path) {
      return partialBuildUri('https')('exercism.org');
    }
    

Változók lexikai scope-ja

Bármely programozási nyelvben a closure-ök szorosan összefüggenek a változók scope-jával. A JavaScriptben háromféle lexikai scope létezik a változók számára:

  1. globális scope: Ezek azok a változók, amelyeket függvényeken és blokkokon kívül deklarálunk.
  2. függvény-scope: Ezek azok a változók, amelyeket egy függvényen belül a var kulcsszóval deklarálunk.
  3. blokk-scope: Ezek azok a változók, amelyeket egy blokkon ({...}) belül a let és a const kulcsszóval deklarálunk.

A gyakorlatban closure gyakran akkor jön létre, amikor egy függvény (vagy blokk) egy külső scope változóját használja. A JavaScriptben ez átláthatóan támogatott, ezért a closure-öket gyakran anélkül használjuk, hogy külön hivatkoznánk rájuk.

Függvény-scope

A var kulcsszó a függvény-scope-hoz kötött változókat definiálja. Ez azt jelenti, hogy a var-ral definiált változók mindenhol elérhetők abban a függvényben, ahol definiáltuk őket, valamint minden egymásba ágyazott lexikai scope-ban (legyen az függvény vagy blokk).

{
  var five = 5;
}

// This will succeed because 'five' exists in the same scope
var tenTimes = five * 10;

Blokk-scope

A let és a const kulcsszó a blokk-scope-hoz kötött változókat definiálja. A let egy módosítható változót definiál, amelynek az értéke többször is beállítható, és lehet definiálva inicializálás nélkül. A const olyan változót definiál, amelyet a definiálásakor inicializálni kell, és az értéke utána nem változhat. Ha a const változó értéke primitív, akkor az nem módosítható. Ha a const változó értéke referenciatípus, például egy tömb vagy objektum, akkor maga a referencia nem változhat, de a tömb tartalma módosítható.

Nézzük ezt a blokkot:

// 'two' is defined at the top-level, therefore available to the global-scope
const two = 2;

{
  // This succeeds, as 'two' is available from the outer lexical scope
  const oneLess = two - 1;
}

// This throws an error because oneLess is not defined outside of the previous inner lexical scope
console.log(oneLess);

Bár a kapcsos zárójeleket ({...}) tetszőlegesen használhatjuk blokkok létrehozására, leggyakrabban elágazások, függvények és osztályok körül találkozunk velük.

const PI = 3.14;

// This function uses a closure for the value of PI (π)
function areaOfCircle(radius) {
  return PI * radius * radius;
}
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg

Tanuld meg a(z) Lezárások fogalmat