javascript-匿名函数、闭包常见问题(2).

★★★★来看一个经典的例子

 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();
原文地址:https://www.cnblogs.com/VanqusherCsn/p/4316419.html