二十五岁时我们都一样愚蠢、多愁善感,喜欢故弄玄虚,可如果不那样的话,五十岁时也就不会如此明智。
标题:JavaScript函数闭包
JavaScript变量属于 本地 或者 全局 范围。
使用 闭包 可以让私有变量成为可能。
全局变量
一个函数可以访问所有定义在函数 内部 的变量,像这样:
function myFunction() { var a = 4; return a * a; }但是函数也可以访问定义在函数 之外 的变量,像这样:
var a = 4; function myFunction() { return a * a; }在最后一个例子中,a是一个全局变量.
在网页中,全局变量属于窗口window对象.
全局变量可以被页面(和窗口)中所有脚本使用(和更改)
在第一个例子中,a是一个局部变量.
局部变量只能在定义的函数内使用。它是隐藏的在其他函数和其他脚本代码.
具有相同名称的全局变量和局部变量是不同的变量。修改一个,不修改其他.
没有关键字var创建的变量,总是全局的,即使它们是在函数中创建的.
变量的生命周期
全局变量只要你的应用程序(你的窗口/你的网页)存在,它就存在。
局部变量生命周期较短。它们在函数被调用时被创建,当函数完成时被删除。
一个计数器
假设你想使用一个变量来计数一些东西,你希望这个计数器对所有函数都可用。.
可以使用全局变量和函数来增加计数器:
var counter = 0; function add() { counter += 1; } add(); add(); add(); // the counter is now equal to 3计数器只被add()函数改变。
问题是,页上的任何脚本可以改变计数器,无需调用add()。
如果我在函数中声明计数器,没有调用的时候没有人能改变它 add():
function add() { var counter = 0; counter += 1; } add(); add(); add(); // the counter should now be 3, but it does not work !它没有工作!每次我调用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(); // the counter is now 3实例说明
变量add被分配了自调用函数的返回值
自调用函数只运行一次. 它将counter设置为零(0),并返回函数表达式.
这样 add 变成了一个函数. "精彩的" 部分是它可以在父作用域中访问counter。
这就是所谓的 JavaScript 闭包. 它使函数有“私有”变量成为可能.
counter受匿名函数的作用域保护, 并且只能使用add函数修改.
闭包是一个函数,即使父函数关闭后,也可以访问父作用域.