★★★★来看一个经典的例子
1 //想实现的是 arr[0]=0,arr[1]=1,arr[2]=2...arr[4]=4 2 function box() 3 { 4 var arr=[]; 5 6 for(var i=0; i<5; i++) 7 { 8 arr[i]=function() 9 { 10 return i; 11 }; 12 } 13 14 //循环已经执行完毕, i最终是4++ =>5 , 那么最终是5 15 //那么你再从里面调用 每个匿名函数的i 那必然是5 16 return arr; //★这里很重要 我们返回出的是 已经循环结束的i 17 } 18 19 var b =box(); 20 21 for(var i=0; i<5; i++) 22 { 23 alert(b[i]()); //=>5,5,5,5,5 24 }
★修改1
1 function box() 2 { 3 var arr = []; 4 for(var i=0; i<5; i++) 5 { 6 arr[i]=(function(num) //通过自我及时 执行匿名函数 7 { 8 return num; 9 })(i); 10 } 11 return arr; 12 } 13 14 var b=box(); 15 for(var i=0; i<5; i++) 16 { 17 alert(b[i]); //这里的是b[i] 18 }
★修改2
1 function box() 2 { 3 var arr = []; 4 for(var i=0; i<5; i++) 5 { 6 arr[i]=(function(num) 7 { 8 //num其实在这里 9 return function() 10 { 11 return num; //因为闭包可以将变量驻留在内存中,和上面的累加是一样的 12 } 13 })(i); 14 } 15 //已经执行完毕了,num为什么可以0,1,2,3,4 16 return arr; 17 } 18 19 var b=box(); 20 //console.log(b); 21 for(var i=0; i<5; i++) 22 { 23 alert(b[i]()); 24 }
看一个小技巧
1 var b=function() 2 { 3 alert('Lee'); 4 }(i) 5 6 //所以改2的循环是可以改成 如下 7 arr[i]=function(num) 8 { 9 return function() 10 { 11 return num; 12 } 13 }(i);
1 //犀牛看到的一种写法,问了一下应该是 代码规范相关文档 2 //http://suqing.iteye.com/blog/1981591 3 //https://github.com/linlincat/Development 4 5 var uniq = (function(counter){ 6 7 return function(){return counter++;}; 8 }(0));
★★闭包中的this
1 var box= { 2 getThis:function() 3 { 4 return function() 5 { 6 return this; 7 } 8 } 9 } 10 //如果this在全局范围就是window,如果在对象内部就指向这个对象,而闭包却在运行时指向window的,因为闭包并不属于这个都属性或方法 11 //因为闭包在运行的时候 是驻留在内存中的 就是模拟了全局 所以指向了window. 12 alert(box.getThis()()); //=> window
this 指向 要看运行时上下文.而闭包却是在运行时指向Window的,因为闭包并不属于这个对象的属性和方法
1 var user ='The Window'; 2 var box={ 3 user:'The Box', 4 getUser:function() 5 { 6 //这里的作用域的this是box 7 return function() 8 { 9 //这里作用域的this是window 10 return this.user; 11 } 12 } 13 } 14 15 //alert(box.getUser()()); //=>The Window 16 //对象冒充 17 alert(box.getUser().call(box)); //The Box
1 var user ='The Window'; 2 var box={ 3 user:'The Box', 4 getUser:function() 5 { 6 var that=this; 7 return function() 8 { 9 return that.user; 10 } 11 } 12 } 13 14 alert(box.getUser()()); //The Box
关于闭包内存泄露的问题[只针对IE浏览器]
1 function box() 2 { 3 var oDiv =document.getElementById('oDiv'); 4 var text =oDiv.innerHTML; 5 oDiv.onclick=function() 6 { 7 alert(text); //引用的只是oDiv.innerHTML的值 8 }; 9 10 oDiv=null; //解除引用,等待回收 11 alert(oDiv); 12 } 13 box();