JavaScript闭包
闭包
内部函数拥有比它的外部函数更长的生命周期!!!
函数可以访问它被创建时所处的上下文环境!!!
内部函数能访问外部函数的实际变量,而无需复制!
实例:
/*
* 点击li标签时,调用其onclick事件,执行代码段function(){alert(i);}
* 此时,i在全局中的值为4
*/
window.onload = init;
function init(){
var lis = document.getElementById("wrap").getElementsByTagName("li");
var i;
for(i=0;i<lis.length;i++){
lis[i].onclick = function(){
alert(i); // 结果:点击每个li都弹出4
};
}
}
/*
* 执行onclick过程,调用(2)处函数,并不是调用(1)处函数;
* 而(1)也存活,存活域中不存在变量i
*/
window.onload = init;
function init(){
var lis = document.getElementById("wrap").getElementsByTagName("li");
var i;
for(i=0;i<lis.length;i++){
lis[i].onclick = function(i){ //(1)
return function(){ //(2)
alert(i);
}; // 结果:undefined
}();
}
}
/*
* 执行onclick过程,调用(2)处函数,并不是调用(1)处函数;
* 而(1)也存活,存活域中不存在变量i;
* 变量i在循环时暂存储到了匿名函数中
*/
window.onload = init;
function init(){
var lis = document.getElementById("wrap").getElementsByTagName("li");
var i;
for(i=0;i<lis.length;i++){
lis[i].onclick = (function(i){ //(1)
return function(){ //(2)
alert(i);
}; // 结果:正确
})(i);
}
}
/*
* 页面加载时,在for循环中,为每个li标签绑定onclick事件;
* 执行函数liclick(),依次弹出0,1,2,3
*/
window.onload = init;
var liclick = function(index){
alert(index);
}
function init(){
var lis = document.getElementById("wrap").getElementsByTagName("li");
var i;
for(i=0;i<lis.length;i++){
lis[i].onclick = liclick(i); // 结果:加载页面时自动弹出0,1,2,3
}
}
/*
* 页面加载时,在for循环中,为每个li标签绑定onclick事件;
* 执行函数liclick(),该函数返回值为一个匿名函数,i暂存到匿名函数中,不会立即执行;
* 用户点击li标签时,触发匿名函数
*/
window.onload = init;
var liclick = function(index){
return function(){
alert(index);
}
}
function init(){
var lis = document.getElementById("wrap").getElementsByTagName("li");
var i;
for(i=0;i<lis.length;i++){
lis[i].onclick = liclick(i); // 结果:正确
}
}
总结
- 给对应的li添加一个属性记录是第几个如 id=0,1,2,3
- 将函数外移,避免函数套函数