JavaScript 闭包


JavaScript 变量可所以部分变量或大局变量。

私有变量能够用到闭包。


大局变量

函数能够拜访是有函数内部界说的变量,如:

实例

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

测验一下 »

函数也能够拜访函数外部界说的变量,如:

实例

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

测验一下 »

后边一个实例中, a 是一个 大局 变量。

在web页面中大局变量归于 window 目标。

大局变量可应用于页面上的一切脚本。

在第一个实例中, a 是一个 部分 变量。

部分变量只能用于界说它函数内部。关于其他的函数或脚本代码是不可用的。

大局和部分变量即使称号相同,它们也是两个不同的变量。修正其间一个,不会影响另一个的值。

Note 变量声明是假如不运用 var 关键字,那么它便是一个大局变量,即使它在函数内界说。


变量生命周期

大局变量的效果域是大局性的,即在整个JavaScript程序中,大局变量处处都在。

而在函数内部声明的变量,只在函数内部起效果。这些变量是部分变量,效果域是部分性的;函数的参数也是部分性的,只在函数内部起效果。


计数器窘境

想象下假如你想计算一些数值,且该计数器在一切函数中都是可用的。

你能够运用大局变量,函数设置计数器递加:

实例

var counter = 0;

function add() {
    counter += 1;
}

add();
add();
add();

// 计数器现在为 3

测验一下 »

计数器数值在履行 add() 函数时发生变化。

但问题来了,页面上的任何脚本都能改动计数器,即使没有调用 add() 函数。

假如我在函数内声明计数器,假如没有调用函数将无法修正计数器的值:

实例

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

add();
add();
add();

// 原意是想输出 3, 但适得其反,输出的都是 1 !

测验一下 »

以上代码将无法正确输出,每次我调用 add() 函数,计数器都会设置为 1。

JavaScript 内嵌函数能够处理该问题。


JavaScript 内嵌函数

一切函数都能拜访大局变量。  

实际上,在 JavaScript 中,一切函数都能拜访它们上一层的效果域。

JavaScript 支撑嵌套函数。嵌套函数能够拜访上一层的函数变量。

该实例中,内嵌函数 plus() 能够拜访父函数的 counter 变量:

实例

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

测验一下 »

假如咱们能在外部拜访 plus() 函数,这样就能处理计数器的窘境。

咱们相同需求保证 counter = 0 只履行一次。

咱们需求闭包。


JavaScript 闭包

还记得函数自我调用吗?该函数会做什么?

实例

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

add();
add();
add();

// 计数器为 3

测验一下 »

实例解析

变量 add 指定了函数自我调用的回来字值。

自我调用函数只履行一次。设置计数器为 0。并回来函数表达式。

add变量能够作为一个函数运用。十分棒的部分是它能够拜访函数上一层效果域的计数器。

这个叫作 JavaScript 闭包。它使得函数具有私有变量变成或许。

计数器受匿名函数的效果域维护,只能经过 add 办法修正。

Note 闭包是可拜访上一层函数效果域里变量的函数,即使上一层函数现已封闭。