认识闭包函数
简单描述,闭包函数就是嵌套结构的函数,在一个函数内定义的一个函数。作为闭包的必要条件,内部函数应该访问外部函数中声明的私有变量、参数或其他内部函数。当上述的两个必要条件实现后,此时如果在外部函数外调用这个内部函数,它就成为了闭包函数。
function f(x){
var a=x;
var b=function(){
return a;
};
a++;
return b;
}
var c=f(8);
alert(c());
使用闭包
使用闭包结构能够跟踪动态环境中数据的实时变化,并及时存储。
function f(){
var a=2;
var b=function(){
return a;
};
a++;
return b;
}
var c=f();
alert(c());
闭包不会因为外部函数环境的注销而消失,而是始终存在。
<button onclick="f()">按钮1:(f())()</button><br /><br />
<button onclick="b()">按钮2:(b=function(){alert(a);})()</button><br /><br />
<button onclick="c()">按钮3:(c=function(){alert(a);})()</button><br /><br />
<button onclick="d(100)">按钮4:(d=function(x){a=x;})(100)</button><br />
function f(){
var a=2;
b=function(){
alert(a);
}
c=function(){
a++;
}
d=function(x){
a=x;
}
}
单击按钮1>单击按钮3>单击按钮2
单击按钮1>单击按钮4>单击按钮2
利用闭包存储变量所有变化的值。
function f(x){
var a=[];
for(var i=0;i<x.length;i++){
var temp=x[i];
a.push(function(){
alert(temp+' '+x[i]);
});
}
return a;
}
function e(){
var a=f(["a","b","c"]);
for(var i=0;i<a.length;i++){
a[i]();
}
}
e();
function f(x){
var a=[];
for(var i=0;i<x.length;i++){
var temp=x[i];
a.push(
(function(temp,i){
return function(){
alert(temp+' '+x[i]);
}
})(temp,i)
);
}
return a;
}
function e(){
var a=f(["a","b","c"]);
for(var i=0;i<a.length;i++){
a[i]();
}
}
e();
利用同一个闭包体声明多个闭包。同一个闭包,通过分别引用,能够在当前环境中生成多个闭包。
function f(x){
var temp=x;
return function(x){
temp+=x;
alert(temp);
}
}
var a=f(50);
var b=f(100);
a(5);
b(10);
定义闭包存储器
闭包常见的用法就是为了要执行的函数提供参数。例如为事件属性传递动作,为定时器函数传递行为等。
function f(a,b){
return function(){
a(b);
}
}
var c=f(alert,"hello!");
var d=setTimeout(c,1000);
使用闭包作为值来进行传递。当文档加载完毕后,会自动弹出一个提示框。
function f(a,b){
return function(){
a(b);
}
}
var c=f(alert,"hello!");
window.onload=c;
通过闭包可以使作为缓存器的数组与依赖它的函数关联起来,实施优雅的打包,同时,也能够维持在全局命名空间外指定的缓冲数组的属性名,免除了名称冲突和意外交互的危险。
var f=function(){
var a=[1,2,3,4,5,6,7,8];
return function(a1,a2,a3,a4,a5){
a[0]=a1;
a[1]=a2;
a[2]=a3;
a[3]=a4;
a[4]=a5;
return a.join("-");
};
}();
var a=f(11,12,13,14,15);
var b=f("a","b","c","d","e");
alert(a);
alert(b);
在事件处理中应用闭包
为页面中特定的元素或标签绑定几个事件,使其能够在鼠标经过、移开和单击时呈现不同的背景颜色。
element.onclick=function(){ // 单击事件
element.style.backgroundColor="red";
}
element.onmouseover=function(){ //鼠标经过事件
element.style.backgroundColor="blue";
}
element.onmouseout=function(){ //鼠标移开事件
element.style.backgroundColor="pink";
}
定义一个函数,通过参数形式来定位预控制的标签,然后调用该函数。
把注册事件处理函数与定义相应的事件处理函数分离。
function f(name){ //为指定标签绑定事件的函数
var e=document.getElementsByTagName(name);
if(e){
for(var i in e){ //遍历标签中每个元素
e[i].onclick=function(){
e[i].onclick=function(){
e[i].style.backgroundColor="red";
}
e[i].onmouseover=function(){
e[i].style.backgroundColor="blue";
}
e[i].onmouseout=function(){
e[i].style.backgroundColor="pink";
}
}
}
}
}
function f(name){
var e=document.getElementsByTagName(name);
if(e){
for(var i in e){
e[i].onclick=click;
e[i].onmouseover=over;
e[i].onmouseout=out
}
}
}
f.click=function(event,element){
element.style.backgroundColor="red";
}
f.over=function(event,element){
element.style.backgroundColor="blue";
}
f.out=function(event,element){
element.style.backgroundColor="pink";
}
例子
<p>hello</p>
<p>good</p>
<p>throw</p>
function f(o,m){
return function(e){
e=e||window.event; //获取事件处对象
return o[m](e,this);
}
}
function g(id){
return function(){
var e=document.getElementsByTagName(id);
if(e){
for(var i in e){
e[i].onclick=f(g,"click");
e[i].onmouseover=f(g,"over");
e[i].onmouseout=f(g,"out");
}
}
}
}
g.click=function(event,element){
element.style.backgroundColor="red";
}
g.over=function(event,element){
element.style.backgroundColor="blue";
}
g.out=function(event,element){
element.style.backgroundColor="pink";
}
window.onload=g("p");