javascript闭包

本文深入讲解JavaScript中的闭包概念,包括闭包的工作原理、优点及其应用场景。通过具体实例介绍了闭包如何帮助实现变量持久化及模块化代码设计,并探讨了闭包在循环中的应用以及在不同浏览器环境下可能遇到的问题。

  每次调用javascript函数的时候,都会为之创建一个新的对象用来保存局部变量,把这个对象添加至作用域链中。

  当函数返回的时候,就从作用域链中将这个绑定变量的对象删除。如果不存在嵌套的函数,也没有其他引用指向这个绑定对象,它就会被当做垃圾回收掉。

  如果定义了嵌套的函数,每个嵌套的函数都各自对应一个作用域链,并且这个作用域链指向一个变量绑定对象,但如果这些嵌套的函数对象在外部函数中保存下来,那么它们也会和所指向的变量绑定对象一样当做垃圾回收。

  但是如果这个函数定义了嵌套的函数,并将它作为返回值返回或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套的函数。它就不会被当做垃圾回收,并且它所指向的变量绑定对象也不会被当做垃圾回收。

 


1.什么是闭包?

  简单的说,就是函数嵌套函数,

  内部函数可以引用外部函数的参数和变量

  参数和变量不会被垃圾回收机制所回收

Eg:  

function  aaa( ){

var   a=5;

function   bbb( ){

console.log( a );

}

return bbb;

}

var  c=aaa();

c();//5


 

闭包的优点?

1)希望或者说可以使一个变量长期驻扎在内存当中

2)避免全局污染

首页看一个全局变量的例子:

eg:

   var a=1;

   function  aaa(){

    a++;

    console.log(a);

  }

  aaa();//2

  aaa();//3

然后把这个变量变成局部变量来看一下:

  function  aaa(){

     var a=1;

     a++;

    console.log(a);

}

  aaa();//2

  aaa();//2

接下来咱们改成闭包:

 

function  aaa() {

var  a=1;

return function(){

    a++;

   console.log( a );

}

}

var b=aaa();

b();//2

b();//3

还可以这样写:

 var  aaa=( function( ) {

   var a=1;

   return function(){

       a++;

      console.log(a);

  }

} ) ( );

aaa();//2

aaa();//3

那闭包用在哪里呢?看下面例子

 

1)模块化代码

   var  aaa=( function(){

         var a=1;

         function  bbb() {

            a++;

            console.log( a );

         }

         function  ccc() {

            a++;

            console.log( a );

         }

        return {

          b:bbb,

          c:ccc

         }

      } )( );

      aaa.b();//2

      aaa.c();//3

      aaa.ccc();//报错

 

继续往下看:

 

2)在循环中直接找到对应元素的索引

 eg: <ul>

       <li>11</li>

       <li>11</li>

       <li>11</li>

     </ul>

window.onload=function() {

var  aLi=document.getElementsByTagName( li );

for( var  i=0; i< aLi.length; i++){

    aLi [ i ].onclick=function(){

       alert(i);//连续弹出三次3

    }

}

}

上面没有达到闭包效果,那么怎么改写呢?看下面

window.onload=function() {

var  aLi=document.getElementsByTagName( ‘li’ );

for( var  i=0; i< aLi.length; i++){

    ( function( i){

        aLi [ i ].onclick=function( ){

       alert(i);//连续弹出三次,分别0 1 2

       }

    } )( i );

}

}

还可以这样改写:

window.onload=function() {

var  aLi=document.getElementsByTagName( ‘li’ );

for( var  i=0; i< aLi.length; i++){

        aLi [ i ].onclick=(function( i ){

       return function(){

          alert(i);//连续弹出三次,分别0 1 2

       }

     })( i );

     }

}

 


 

闭包注意的地方?继续往下看

IE浏览器会出现或引起内存泄露,如何解决?

eg:

<div id=” d1”> 555</div>

window.onload=function () {

 var oDiv=document.getElementById(‘d1’);

     oDiv.onclick=function(){  //变量引用内部函数

        alert(oDiv.id);      //内部函数引用外部对象

}

//这时候就会出现内存泄露,应该这样解决

window.onunload=function(){

    oDiv.omclick=null;

}

}

还可以这样解决:

window.onload=function () {

 var oDiv=document.getElementById(‘d1’);

    var id=oDiv.id;

         oDiv.onclick=function(){  

           alert(id);      

    }

    oDiv=null;

}

}

 

转载于:https://www.cnblogs.com/luoluoweb/p/5765172.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值