JavaScript Closures

JavaScript variabler tilhørerlokalellerGlobaleKontekst.

Globale variabler kan tilgås gennem闭包kan implementere lokale (private).

Globale variabler

Funktioner kan tilgå funktionerIndreDefinerede variabler, såsom:

实例

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

亲自试一试

Men funktioner kan også tilgå funktionerEksternDefinerede variabler, såsom:

实例

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

亲自试一试

I det sidste eksempela erGlobaleVariabler.

I en web-side, er globale variabler en del af window-objektet.

Globale variabler kan bruges og ændres af alle scripts på siden (og i vinduet).

I det første eksempela erLokaleVariabler.

Lokale variabler kan kun bruges i den funktion, de er defineret i. For andre funktioner og skriptkoder er de utilgængelige.

Variabler med samme navn er forskellige variabler. Ændring af en ændrer ikke den anden.

ikke gennemnøgleord var Oprettede variabler er altid globale, selvom de oprettes i en funktion.

Livscyklus for variabler

Globale variabler lever så længe som din applikation (vindue, web-side).

Lokale variabler lever ikke længe. De oprettes ved funktion kald og slettes, når funktionen afsluttes.

En tællers dilemma

Antag, at du vil bruge en variabel til at tælle, og at du ønsker, at denne tæller skal være tilgængelig for alle funktioner.

Du kan bruge globale variabler og funktioner til at øge tælleren:

实例

// Initialiser tælleren
var counter = 0;
// Funktion til at øge tælleren
function add() {
  counter += 1;
}
// Kald add() tre gange
add();
add();
add();
// På dette tidspunkt skulle tælleren være 3

亲自试一试

Løsningen ovenfor har et problem: Enhver kode på siden kan ændre tælleren uden at kalde add().

For add() funktionen bør tælleren være lokal for at forhindre, at anden kode ændrer den:

实例

// Initialiser tælleren
var counter = 0;
// Funktion til at øge tælleren
function add() {
  var counter = 0; 
  counter += 1;
}
// Kald add() tre gange
add();
add();
add();
// På dette tidspunkt skulle tælleren være 3. Men det er 0.

亲自试一试

Det er ikke brugbart, fordi vi viser den globale tæller i stedet for den lokale tæller.

Ved at lade funktionen returnere det, kan vi fjerne den globale tæller og tilgå den lokale tæller:

实例

// Funktion til at øge tælleren
function add() {
  var counter = 0; 
  counter += 1;
  return counter;
}
// Kald add() tre gange
add();
add();
add();
// På dette tidspunkt skulle tælleren være 3. Men det er 1.

亲自试一试

Det er ikke brugbart, fordi vi altid nulstiller den lokale tæller, når vi kalder funktionen.

JavaScript's indre funktioner kan løse dette problem.

JavaScript-indlejrede funktioner

Alle funktioner har ret til at tilgå den globale kontekst.

Faktisk har alle funktioner i JavaScript ret til at tilgå deres 'øverste' kontekst.

JavaScript understøtter indlejrede funktioner. Indlejrede funktioner kan tilgå den øverste kontekst.

I dette eksempel, den indre funktion plus() kan tilgå funktionens forældre counter Tællervariabelen:

实例

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

亲自试一试

这样即可解决计数器困境,如果我们能够从外面访问 plus() 函数。

我们还需要找到只执行一次 counter = 0 的方法。

我们需要闭包(closure)。

JavaScript Closures

记得自调用函数吗?这种函数会做什么呢?

实例

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
add();
add();
add();
// 计数器目前是 3 

亲自试一试

例子解释

变量 add 的赋值是自调用函数的返回值。

这个自调用函数只运行一次。它设置计数器为零(0),并返回函数表达式。

这样 add 成为了函数。最“精彩的”部分是它能够访问父作用域中的计数器。

这被称为 JavaScript 闭包。它使函数拥有“私有”变量成为可能。

计数器被这个匿名函数的作用域保护,并且只能使用 add 函数来修改。

闭包指的是有权访问父作用域的函数,即使在父函数关闭之后。