闭包函数,就是嵌套结构的函数,在一个函数内定义的一个函数。作为闭包的必要条件,内部函数应该访问外部函数中声明的私有变量,参数,或者其他内部函数。当上述两个必要条件实现后,此时如果在外部函数外调用这个内部函数,他就成为了闭包函数。
示例
fuction f(x){ //外部函数
var a = x; //外部函数中的局部变量,并把参数传递给他
var b = function(){ //内部函数
return a; //访问外部函数中的局部变量
};
a++; //访问后,动态更新外部函数的变量
return b; //返回内部函数
}
var c = f(5); //调用外部函数
alert(c()); //调用内部函数,返回值为6
如果没有闭包函数的作用,那么这种数据寄存和传递就无法实施。
fuction f(x){
var a = x;
var b = a; //直接把局部变量的值传递给局部变量b
a++;
return b; //返回局部变量b
}
var c = f(5);
alert(c); 返回值为5
通过上面示例可以很直观的看到,在没有闭包函数的辅助下,第8行代码执行后返回的值并没有与外部函数的局部变量a最后更新的值保持一致。
一旦函数被调用执行,则闭包体也会随之诞生,闭包是函数运行期中的一个动态环境。与函数的静态性是截然不同的概念,由于每个函数都是一个独立的上下文环境。因此当闭包函数被再次执行或者通过某种方法进入函数体时,就可以换取闭包片。
使用闭包
使用闭包结构能够跟踪动态环境中数据的实时变化,并即时存储
function f(){
var a = 1;
var b = function(){
return a;
}
a++;
return b;
}
var c = f();
alert(c());
在上面示例中,闭包中的变量a,其存储的值并不是从上面行变量a的值的简单复制,而是继续引用外函数定义的局部变量a中的值,直到外部函数f调用返回。
<body>
<button onclick="f()">按钮1:(f())()</button><br/>
<button onclick="b()">按钮2:(b=function(){alert(a);})</button><br/>
<button onclick="c()">按钮3:(c=funtion(){a++;})</button><br/>
<button onclick="d(100)">按钮4:(d = function(x) {a=x;})</button><br/>
</body>
<script type="text/javascript">
function f(){
var a = 1;
b = function(){
alert(a);
}
c = function(){
a++;
}
d = function(x){
a=x;
}
}
</script>
在上面的示例中,普通函数f中定义了3个闭包函数,它们分别指向并寄存局部变量a的值。并根据不同的操作动态跟踪变量a的值。
当在浏览器中预览时,首先单击按钮1 调用函数f,将生成3个闭包,并且3个闭包同时指向局部变量a的引用。因此当函数f返回时,3个闭包函数都没有被注销。而变量a由于被闭包引用而继续存在。这时如果直接单机按钮2~4,则由于没有在系统中生成闭包,则会编译错误。
单击按钮3 则将动态递增变量a的值,此时如果单机按钮2,则会弹出提示值为2,如果单击按钮3 则向变量a传递值100,将动态改变闭包中寄存的值,此时如果单击按钮2则会提示值为100
闭包常见的用法就是为要执行的函数提供参数,例如,为时间属性传递动作,为定时器函数传递行为等。
function f(a,b){
return function(){
a(b);
}
}
var c = f(alert,"hello.world");
var d =setTimeout(c,1000);
但是传递函数引用的同时就无法调用函数。