Uzavření funkcí JavaScriptu


Obsah

    Zobrazit obsah


Proměnné JavaScriptu mohou patřit k místním resp globální rozsah.

Globální proměnné lze nastavit jako místní (soukromé) pomocí uzavírek.


Globální proměnné

funkce může přistupovat ke všem proměnným definovaným uvnitř funkce, jako je tato:

Příklad

function myFunction() {
    let a = 4;
    return a * a;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>
<p>A function can access variables defined inside the function:</p>

<p id="demo"></p>

<script>
myFunction();

function myFunction() {
  let a = 4;
  document.getElementById("demo").innerHTML = a * a;
}
</script>

</body>
</html>

Ale funkce může také přistupovat k proměnným definovaným mimo funkci, jako je tato:

Příklad

let a = 4;
function myFunction() {
    return a * a;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>
<p>A function can access variables defined outside the function:</p>

<p id="demo"></p>

<script>
let a = 4;
myFunction();

function myFunction() {
  document.getElementById("demo").innerHTML = a * a;
} 
</script>

</body>
</html>

V posledním příkladu je a globální variabilní.

Na webové stránce globální proměnné patří ke stránce.

Globální proměnné mohou používat (a měnit) všechny ostatní skripty na stránce.

V prvním příkladu je a místní variabilní.

Lokální proměnnou lze použít pouze uvnitř funkce, kde je definována. To je skrytý před ostatními funkcemi a jiným skriptovacím kódem.

Globální a lokální proměnné se stejným názvem jsou různé proměnné. Úprava jednoho nemění druhého.

Poznámka

Proměnné vytvořené bez klíčového slova deklarace (var, let nebo const) jsou vždy globální, i když jsou vytvořeny uvnitř funkce.

Příklad

function myFunction() {
  a = 4;
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>
<p>Variables created without a declaration keyword (var, let, or const) are always global,
even if they are created inside a function.:</p>

<p id="demo"></p>

<script>
myFunction();
document.getElementById("demo").innerHTML = a * a;

function myFunction() {
  a = 4;
} 
</script>

</body>
</html>


Variabilní životnost

Globální proměnné fungují, dokud není stránka zahozena, například při navigaci na jinou stránku nebo zavřete okno.

Místní proměnné mají krátkou životnost. Jsou vytvořeny, když je funkce vyvolán a po dokončení funkce odstraněn.


Protidilema

Předpokládejme, že chcete pro počítání něčeho použít proměnnou a chcete toto počítadlo, aby byly dostupné všechny funkce.

Ke zvýšení počítadla můžete použít globální proměnnou a funkci:

Příklad

 // Initiate counter
let counter = 0;
// Function to increment 
  counter
function add() {
  counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The counter should now be 3

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Function Closures</h2>
<p>Counting with a global variable.</p>

<p id="demo"></p>

<script>
// Initiate counter
let counter = 0;

// Function to increment counter
function add() {
  counter += 1;
}

// Call add() 3 times
add();
add();
add();

// The counter should now be 3
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>

</body>
</html>

S výše uvedeným řešením je problém: Jakýkoli kód na stránce může změnit počítadlo, bez volání add().

Počítadlo by mělo být lokální pro funkci add(), aby se zabránilo změně jiného kódu to:

Příklad

 // Initiate counter
let counter = 0;
// Function to increment 
  counter
function add() {
  let counter = 0; 
  
  counter += 1;
}
// 
  Call add() 3 times
add();
add();
add();
//The counter should 
  now be 3. But it is 0

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>

<p id="demo"></p>

<script>
// Initiate counter
let counter = 0;

// Function to increment counter
function add() {
  let counter = 0; 
  counter += 1;
}

// Call add() 3 times
add();
add();
add();

// The result is not 3 because you mix up the globaland local counter
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>

</body>
</html>

Nefungovalo to, protože místo místního zobrazujeme globální počítadlo čelit.

Můžeme odstranit globální počítadlo a získat přístup k místnímu počítadlu tím, že necháme funkce to vrátí:

Příklad

 // Function to increment 
  counter
function add() {
  let counter = 0; 
  
  counter += 1;
  return counter;
}
// 
  Call add() 3 times
add();
add();
add();
//The counter should 
  now be 3. But it is 1.

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Closures</h2>
<p>Counting with a local variable.</p>

<button type="button" onclick="myFunction()">Count!</button>

<p id="demo">0</p>

<script>
// Function to increment counter
function add() {
  let counter = 0;
  counter += 1;
  return counter;
}
// Trying to increment the counter
function myFunction(){
  document.getElementById("demo").innerHTML = add();
}
</script>

</body>
</html>

Nefungovalo to, protože jsme resetovali místní počítadlo pokaždé, když voláme na funkce.

Vnitřní funkce JavaScriptu to může vyřešit.


Vnořené funkce JavaScriptu

Všechny funkce mají přístup ke globálnímu rozsahu.

Ve skutečnosti v JavaScriptu mají všechny funkce přístup k rozsahu „nad“ sebou.

JavaScript podporuje vnořené funkce. Vnořené funkce mají přístup k rozsah „nad“ nimi.

V tomto příkladu má přístup vnitřní funkce plus() do proměnné counter v nadřazené funkci:

Příklad

function add() {
    let counter = 0;
    function plus() {counter += 1;}
  plus();   
 
  return counter; 
}

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>

<p id="demo">0</p>

<script>
document.getElementById("demo").innerHTML = add();
function add() {
  let counter = 0;
  function plus() {counter += 1;}
  plus();  
  return counter; 
}
</script>

</body>
</html>

To by mohlo vyřešit dilema čítače, pokud bychom dosáhli plus() fungovat zvenčí.

Musíme také najít způsob, jak spustit counter=0 pouze jednou.

Potřebujeme uzavření.


Uzávěry JavaScriptu

Pamatujete na samovolné funkce? Co tato funkce dělá?

Příklad

const add = (function () {
  let counter = 0;
  return function () {counter += 1; return counter}
})();
add();
add();
add();

// the counter is now 3

Zkuste to sami →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Closures</h2>

<p>Counting with a local variable.</p>

<button type="button" onclick="myFunction()">Count!</button>

<p id="demo">0</p>

<script>
const add = (function () {
  let counter = 0;
  return function () {counter += 1; return counter;}
})();

function myFunction(){
  document.getElementById("demo").innerHTML = add();
}
</script>

</body>
</html>

Příklad vysvětlen

Proměnná add je přiřazena k návratové hodnotě samovolného funkce.

Samovolná funkce se spustí pouze jednou. Nastaví počítadlo na nulu (0), a vrátí výraz funkce.

Tímto způsobem se add stane funkcí. "Úžasné" na tom je, že má přístup čítač v nadřazeném rozsahu.

Toto se nazývá uzavření JavaScriptu. Umožňuje to aby funkce měla "soukromé" proměnné.

Počítadlo je chráněno rozsahem anonymní funkce, a lze jej změnit pouze pomocí funkce přidat.

Uzavření je funkce, která má přístup k nadřazenému oboru, i když je nadřazená funkce uzavřena.