闭包是一个函数有权访问另一个函数作用域的变量,但有一个需要注意的范围的配置机制,即关闭只能得到任何变量的过去值中所包含的函数。

在下列情况下:


函数创建(){
VaR ARR =新的数组();

对于(var i = 0;i < 10;i + +){
ARR {我} =函数(){
还我;
};
}

报酬;
}

无功c_arr =创造();

对于(var i = 0;i < c_arr.length;i++){
document.write(c_arr {+我+} =+ c_arr {我}()+);
}


实施结果:



表面上看,似乎每个函数返回的例子不同,我的价值,对c_arr { 0 }应该是0的价值,和c_arr { 1 }应该是1的价值,等等。因此,该函数返回10。为什么

因为创建()函数的活动对象保存在每个函数的作用域链中,它们都引用同一个变量,I. for for循环结束时,i的值变成10,每个函数引用保存变量i的同一个变量对象。



我们可以通过创建另一个域名函数来强制闭包行为以满足期望,因此每个位置对应于相应的值。


函数创建(){
VaR ARR =新的数组();

对于(var i = 0;i < 10;i + +){
ARR {我} =功能(NUM){
返回函数(){
返回num;
};
}(一);
}

报酬;
}

无功c_arr =创造();

对于(var i = 0;i < c_arr.length;i++){
document.write(c_arr {+我+} =+ c_arr {我}()+);
}


实施结果:



定义了一个匿名函数,并立即将一个匿名函数分配给数组。这里的匿名函数有一个参数num,这是价值的最终的功能恢复。我们通过在变我当每个函数被调用时,由于函数的参数是按值传递的变量的当前值的值,我被分配到在匿名函数中参数的数值,用于访问Num创建并返回关闭,以便在到达数组的每个功能都有一份自己的num变量,所以它可以返回不同的值。

经典的例子

让我们看一个经典的例子。假设页面有一组按钮标签。我们使用脚本将单击事件绑定到组按钮标记,当单击时我们可以弹出这些标记。




弗斯特
第二
第三
第四




var obj = document.getelementsbytagname(按钮);
对于(var i = 0;i < obj.length;i++){
obj {我}。onclick =函数(){
警报(一);
};
}




单击每个按钮结果



表面上看来,单击每个标签应该弹出不同的数字。

第一个应该是0个;

第二应打1;

所以在u3002

结果是所有的按钮都弹出4,显然这不是我们想要的结果。

让我们改变程序。




弗斯特
第二
第三
第四




var obj = document.getelementsbytagname(按钮);
对于(var i = 0;i < obj.length;i++){
obj {我}。onclick=功能(NUM){
返回函数(){
警报(努姆);
}
}(一);
}




点击第二



点击第四



我们只需要在函数中建立一个匿名函数来与上面共享相同的用例,可以实现一个匿名函数来捕获外部变量i,这将导致每个按钮的i值不同。