• javascript中的闭包


    主要分三部分说:

    一、什么是闭包?二、闭包有什么好处?应用在哪里?三、闭包需要注意的地方?

    1、什么是闭包?

    第一个特点:可以是函数嵌套函数 

       function a(){
           function b(){}
       }

    第二个特点:内部函数可以引用外部函数的参数和变量

       function  a(a){
            var b=5;
            function b(){
                alert(a);
                alert(b);
            }
        }

    a和b两个变量都要被内部函数b()引用到,会一直驻扎在内存中,不会被垃圾回收的,也就是说参数和变量不会被垃圾回收机制所收回。

    那么什么是js垃圾回收机制呢?

        function a(){
            var a=1;
        }
    alert(a);

    例如,上面写了个普通函数a(),当alert(a)执行完毕后,调用完毕后变量a就不存在了,为了节省内存。

    例子:

     function  a(){
            var a=5;
            function b(){
                alert(a);
            }
            return b;
        }
        var c=a();
        c();      //5

    变量c就是返回的b函数,c()执行的时候 变量a并没有消失,一直驻扎在内存中的,这时会弹出5的.这就是简单的闭包形式。

    2、闭包有什么好处?应用在哪里?

    好处就:

    1.希望一个变量长期驻扎在内存当中

    2.避免全局变量的污染

    var a=1;
        function a(){
            a++;
            alert(a);
        }
        a(); //2
        a(); //3
        alert(a);//1

    a是个全局变量,一直驻扎在内存中,依次执行会累加。

    function a(){
            var a=1;
            a++;
            alert(a);
        }
        a(); //2
        a(); //2

    如果把变量a设置为局部变量,每调用一次代码重新执行,调用后a就不存在,下次调用的时候a还是1;那么怎么能做到a即是局部变量,a又能累计呢?

    这就是闭包所能做到的。

    例2

    function a(){
            var a=1;
            return function () {
               a++;
                alert(a);
            };
        }
        var b=a();
        b(); //2
        b(); //3
        alert(a) //undfined

    构成了函数嵌套函数,当外面的函数执行完毕后,内部函数依旧可以调用到变量a;

    说一下函数声明和函数表达式:

    function a(){
     alert(1);
     }
    //函数声明 a();
    //函数调用

    这样就是函数声明和函数调用;

    (function(){
      alert(1);
    })();

    ()放函数,函数声明就会变成函数表达式,加()直接调用,可以执行。

    至此可以把例2中的代码改写一下

    var a= (function () {
        var a=1;
        return function () {
            a++;
            alert(a);
        }
    })();
    a();//2
    a();//3

    var a=1在外面是调用不到的,这种形式叫做模块化代码,减少全局变量的污染,把内部函数变为私有的,

    这也就是

    3.私有成员的存在(用法)

    var aaa = (function(){
    
        var a = 1;
        
        function bbb(){
            a++;
            alert(a);
        }
        
        function ccc(){
            a++;
            alert(a);
        }
        
        return {
            
            b : bbb,
            c : ccc
            
        }
    
    })();
    
    
    //aaa.b();  //2
    //aaa.c();  //3

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

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <ul>
        <li>11111111111</li>
        <li>11111111111</li>
        <li>11111111111</li>
    </ul>
    
    <script>
        window.onload = function(){
            var aLi = document.getElementsByTagName('li');
    
        for(var i=0;i<aLi.length;i++){
            
         aLi[i].onclick = function(){
             alert(i);//3
             };
        };
        };
    
    </script>
    
    
    
    
    </body>
    </html>

    alert(i)弹出3,为什么呢?很明显,当循环执行结束的时候

     aLi[i].onclick = function(){
             alert(i);//3
             };
        };
    还没执行,当点击的时候才会执行,但此时i已经变成3了。可以利用闭包改写,可以把循环中的i当作个参数穿进去,就之前所说的内部函数可以引用外部函数的参数和变量。
    for(var i=0;i<aLi.length;i++){
    
    (function(i){
    
    aLi[i].onclick = function(){
    alert(i);
    };
    
    })(i);

    把i当成参数穿进去。除了这种写法还有另外一种方式

    for(var i=0;i<aLi.length;i++){
    
    
    aLi[i].onclick = (function(i){
    
    return function(){
    alert(i);
    }
    
    })(i);

    闭包需要注意的IE下会引发内存泄漏

     http://www.cnblogs.com/xhk-yjp/archive/2012/08/29/xhk-yjp-jsbb.html

  • 相关阅读:
    asp.net 邮件发送,使用外部stmp服务器,呵呵!简单例子
    asp.net 新闻采集 简单示例
    JS 计算时间差
    textarea行尾输入多个空格不换行
    mac系统安装redis
    RSA 分段加解密【解决“不正确的长度”的异常】
    C# 获取指定进程的主窗口句柄
    .Net自定义控件之ToolboxBitmap元数据的设置
    提升 SharePoint 代码执行权限
    关于ThreadLocal的使用
  • 原文地址:https://www.cnblogs.com/nifengs/p/5211457.html
Copyright © 2020-2023  润新知