//闭包的概念就是函数嵌套函数 内部函数可以调用外部函数的参数和变量 并且变量贮存在内存中 不会被垃圾回收机制销毁//可以手动销毁//下面介绍闭包的介绍和简单使用 //简单写法 function outer(){ var num=0; function inner(){ num++; return num; } return inner; } var num=outer(); alert(num());//1 alert(num());//2 alert(num());//3 num=null;//手动销毁 //稍微复杂的写法var outer=(function(){ var num=0; return function(){ num++; return num; } })();
alert(outer());//1 alert(outer());//2 alert(outer());//3 //为什么会产生闭包这种情况呢 //首先num被创建在外部函数内部 而且有内部函数对它的引用 所以当函数自执行以后 //num不会被销毁 还是会在内存中 //以上说法不能很好理解闭包这个东西 //下面这些话才可以更好的理解 //就是return 返回的不仅仅是函数 还把函数的所能访问的作用域链(从内到外一直到window)打包返回了 //所以你继续调用还可以访问的到 //总结一句话:函数的作用域取决于被定义时,而不是调用时 /
闭包的好处:
1.希望一个变量长期驻扎在内存当中
2.避免全局变量的污染
3.私有成员的存在
//用法
1.模块化代码
2.在循环中直接找到对应元素的索引
1. var test=(function(){
function init(){alert("游戏加载成功!");}
function start(){alert("开始游戏!");}
return {
init:init,
start:start
};
})();
test.init();
test.start();
/*
这样的好处不言而喻
首先除了test以外的任何对象都访问不到 init 和start 方法
体现了高内聚的特点
维护也好
还可以改成惰性的
*/
2.<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
var getUL=document.getElementById("test");
var allLi=getUI.children;
var len=allLi.length;
for(var i=0;i<len;i++){
allLi[i].onclick=function(){
console.log(i);
}
}
//点击所有的都会是3
因为for循环完毕以后 allLi的点击事件还没有执行 当执行的时候 i已经变成3了
所以当你触发事件的时候 只会输出3
解决方法 :闭包
for(var i=0;i<len;i++){
(function(n){
allLi[n].onclick=function(){
console.log(n);
}
})(i);
}
//当每次for循环的时候 都会自执行匿名函数 并且把当前索引值传进去
当你触发事件的时候 会访问到你之前传进来的参数n 也就是当时for循环的索引值
//下面这种写法也可以
for(var i=0;i<len;i++){
allLi[n].onclick=(function(n){
return function(){
console.log(n);
}
})(i);
}
//同理 目的就是当每次循环的时候 把 i 保存在事件函数所能访问的最近的作用域中
就是一个当时执行i的副本 保存在作用域中 来用
原文地址:https://www.cnblogs.com/liveoutfun/p/9665435.html